You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by og...@apache.org on 2009/04/23 00:57:04 UTC

svn commit: r767705 [13/31] - in /maven/mercury/trunk/mercury-core: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/maven/ src/main/java/org/apache/maven/mercury/ src/main/java/org/apache/maven/mer...

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/HttpServletResponse.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/HttpServletResponse.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/HttpServletResponse.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/HttpServletResponse.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,344 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package org.apache.maven.mercury.spi.http.client;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public interface HttpServletResponse
+{
+    
+    /*
+     * Server status codes; see RFC 2068.
+     */
+
+    /**
+     * Status code (100) indicating the client can continue.
+     */
+
+    public static final int SC_CONTINUE = 100;
+
+    
+    /**
+     * Status code (101) indicating the server is switching protocols
+     * according to Upgrade header.
+     */
+
+    public static final int SC_SWITCHING_PROTOCOLS = 101;
+
+    /**
+     * Status code (200) indicating the request succeeded normally.
+     */
+
+    public static final int SC_OK = 200;
+
+    /**
+     * Status code (201) indicating the request succeeded and created
+     * a new resource on the server.
+     */
+
+    public static final int SC_CREATED = 201;
+
+    /**
+     * Status code (202) indicating that a request was accepted for
+     * processing, but was not completed.
+     */
+
+    public static final int SC_ACCEPTED = 202;
+
+    /**
+     * Status code (203) indicating that the meta information presented
+     * by the client did not originate from the server.
+     */
+
+    public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
+
+    /**
+     * Status code (204) indicating that the request succeeded but that
+     * there was no new information to return.
+     */
+
+    public static final int SC_NO_CONTENT = 204;
+
+    /**
+     * Status code (205) indicating that the agent <em>SHOULD</em> reset
+     * the document view which caused the request to be sent.
+     */
+
+    public static final int SC_RESET_CONTENT = 205;
+
+    /**
+     * Status code (206) indicating that the server has fulfilled
+     * the partial GET request for the resource.
+     */
+
+    public static final int SC_PARTIAL_CONTENT = 206;
+
+    /**
+     * Status code (300) indicating that the requested resource
+     * corresponds to any one of a set of representations, each with
+     * its own specific location.
+     */
+
+    public static final int SC_MULTIPLE_CHOICES = 300;
+
+    /**
+     * Status code (301) indicating that the resource has permanently
+     * moved to a new location, and that future references should use a
+     * new URI with their requests.
+     */
+
+    public static final int SC_MOVED_PERMANENTLY = 301;
+
+    /**
+     * Status code (302) indicating that the resource has temporarily
+     * moved to another location, but that future references should
+     * still use the original URI to access the resource.
+     *
+     * This definition is being retained for backwards compatibility.
+     * SC_FOUND is now the preferred definition.
+     */
+
+    public static final int SC_MOVED_TEMPORARILY = 302;
+
+    /**
+    * Status code (302) indicating that the resource reside
+    * temporarily under a different URI. Since the redirection might
+    * be altered on occasion, the client should continue to use the
+    * Request-URI for future requests.(HTTP/1.1) To represent the
+    * status code (302), it is recommended to use this variable.
+    */
+
+    public static final int SC_FOUND = 302;
+
+    /**
+     * Status code (303) indicating that the response to the request
+     * can be found under a different URI.
+     */
+
+    public static final int SC_SEE_OTHER = 303;
+
+    /**
+     * Status code (304) indicating that a conditional GET operation
+     * found that the resource was available and not modified.
+     */
+
+    public static final int SC_NOT_MODIFIED = 304;
+
+    /**
+     * Status code (305) indicating that the requested resource
+     * <em>MUST</em> be accessed through the proxy given by the
+     * <code><em>Location</em></code> field.
+     */
+
+    public static final int SC_USE_PROXY = 305;
+
+     /**
+     * Status code (307) indicating that the requested resource 
+     * resides temporarily under a different URI. The temporary URI
+     * <em>SHOULD</em> be given by the <code><em>Location</em></code> 
+     * field in the response.
+     */
+
+     public static final int SC_TEMPORARY_REDIRECT = 307;
+
+    /**
+     * Status code (400) indicating the request sent by the client was
+     * syntactically incorrect.
+     */
+
+    public static final int SC_BAD_REQUEST = 400;
+
+    /**
+     * Status code (401) indicating that the request requires HTTP
+     * authentication.
+     */
+
+    public static final int SC_UNAUTHORIZED = 401;
+
+    /**
+     * Status code (402) reserved for future use.
+     */
+
+    public static final int SC_PAYMENT_REQUIRED = 402;
+
+    /**
+     * Status code (403) indicating the server understood the request
+     * but refused to fulfill it.
+     */
+
+    public static final int SC_FORBIDDEN = 403;
+
+    /**
+     * Status code (404) indicating that the requested resource is not
+     * available.
+     */
+
+    public static final int SC_NOT_FOUND = 404;
+
+    /**
+     * Status code (405) indicating that the method specified in the
+     * <code><em>Request-Line</em></code> is not allowed for the resource
+     * identified by the <code><em>Request-URI</em></code>.
+     */
+
+    public static final int SC_METHOD_NOT_ALLOWED = 405;
+
+    /**
+     * Status code (406) indicating that the resource identified by the
+     * request is only capable of generating response entities which have
+     * content characteristics not acceptable according to the accept
+     * headers sent in the request.
+     */
+
+    public static final int SC_NOT_ACCEPTABLE = 406;
+
+    /**
+     * Status code (407) indicating that the client <em>MUST</em> first
+     * authenticate itself with the proxy.
+     */
+
+    public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
+
+    /**
+     * Status code (408) indicating that the client did not produce a
+     * request within the time that the server was prepared to wait.
+     */
+
+    public static final int SC_REQUEST_TIMEOUT = 408;
+
+    /**
+     * Status code (409) indicating that the request could not be
+     * completed due to a conflict with the current state of the
+     * resource.
+     */
+
+    public static final int SC_CONFLICT = 409;
+
+    /**
+     * Status code (410) indicating that the resource is no longer
+     * available at the server and no forwarding address is known.
+     * This condition <em>SHOULD</em> be considered permanent.
+     */
+
+    public static final int SC_GONE = 410;
+
+    /**
+     * Status code (411) indicating that the request cannot be handled
+     * without a defined <code><em>Content-Length</em></code>.
+     */
+
+    public static final int SC_LENGTH_REQUIRED = 411;
+
+    /**
+     * Status code (412) indicating that the precondition given in one
+     * or more of the request-header fields evaluated to false when it
+     * was tested on the server.
+     */
+
+    public static final int SC_PRECONDITION_FAILED = 412;
+
+    /**
+     * Status code (413) indicating that the server is refusing to process
+     * the request because the request entity is larger than the server is
+     * willing or able to process.
+     */
+
+    public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
+
+    /**
+     * Status code (414) indicating that the server is refusing to service
+     * the request because the <code><em>Request-URI</em></code> is longer
+     * than the server is willing to interpret.
+     */
+
+    public static final int SC_REQUEST_URI_TOO_LONG = 414;
+
+    /**
+     * Status code (415) indicating that the server is refusing to service
+     * the request because the entity of the request is in a format not
+     * supported by the requested resource for the requested method.
+     */
+
+    public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
+
+    /**
+     * Status code (416) indicating that the server cannot serve the
+     * requested byte range.
+     */
+
+    public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
+
+    /**
+     * Status code (417) indicating that the server could not meet the
+     * expectation given in the Expect request header.
+     */
+
+    public static final int SC_EXPECTATION_FAILED = 417;
+
+    /**
+     * Status code (500) indicating an error inside the HTTP server
+     * which prevented it from fulfilling the request.
+     */
+
+    public static final int SC_INTERNAL_SERVER_ERROR = 500;
+
+    /**
+     * Status code (501) indicating the HTTP server does not support
+     * the functionality needed to fulfill the request.
+     */
+
+    public static final int SC_NOT_IMPLEMENTED = 501;
+
+    /**
+     * Status code (502) indicating that the HTTP server received an
+     * invalid response from a server it consulted when acting as a
+     * proxy or gateway.
+     */
+
+    public static final int SC_BAD_GATEWAY = 502;
+
+    /**
+     * Status code (503) indicating that the HTTP server is
+     * temporarily overloaded, and unable to handle the request.
+     */
+
+    public static final int SC_SERVICE_UNAVAILABLE = 503;
+
+    /**
+     * Status code (504) indicating that the server did not receive
+     * a timely response from the upstream server while acting as
+     * a gateway or proxy.
+     */
+
+    public static final int SC_GATEWAY_TIMEOUT = 504;
+
+    /**
+     * Status code (505) indicating that the server does not support
+     * or refuses to support the HTTP protocol version that was used
+     * in the request message.
+     */
+
+    public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/HttpServletResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/HttpServletResponse.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableInputStream.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableInputStream.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableInputStream.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableInputStream.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.crypto.api.StreamObserver;
+import org.apache.maven.mercury.crypto.api.StreamObserverException;
+
+
+
+public class ObservableInputStream
+extends FilterInputStream
+{
+    Set<StreamObserver> observers = new HashSet<StreamObserver>();
+
+    public ObservableInputStream(InputStream in)
+    {
+        super(in);
+    }
+
+    public int read(byte[] b, int off, int len)
+    throws IOException
+    {
+        int result = in.read(b, off, len);
+        if (result != -1) 
+        {
+            notifyListeners(b, off, result);
+        }
+        return result;
+    }
+
+   
+    public int read() throws IOException
+    {
+        int ch = in.read();
+        if (ch != -1) 
+        {
+            notifyListeners(ch);
+        }
+        return ch;
+    }
+
+    
+    public void addObserver (StreamObserver o)
+    {
+        synchronized (this.observers)
+        {
+            this.observers.add(o);
+        }
+    }
+    
+    public void addObservers (Collection<? extends StreamObserver> observers)
+    {
+        synchronized (this.observers)
+        {
+            this.observers.addAll(observers);
+        }
+    }
+    
+    private void notifyListeners (byte[]b, int off, int len)
+    throws IOException
+    {
+        synchronized (this.observers)
+        {
+            for (StreamObserver o: this.observers)
+            {
+                try
+                {
+                  o.bytesReady(b, off, len);
+                }
+                catch( StreamObserverException e )
+                {
+                  throw new IOException(e.getMessage());
+                }
+            }
+        }
+    }
+
+    private void notifyListeners (int b)
+    throws IOException
+    {
+        synchronized (this.observers)
+        {
+            for (StreamObserver o: this.observers)
+            {
+                try
+                {
+                  o.byteReady(b);
+                }
+                catch( StreamObserverException e )
+                {
+                  throw new IOException(e.getMessage());
+                }
+            }
+        }
+    } 
+   
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableInputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableInputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableOutputStream.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableOutputStream.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableOutputStream.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableOutputStream.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.maven.mercury.spi.http.client;
+
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.crypto.api.StreamObserver;
+import org.apache.maven.mercury.crypto.api.StreamObserverException;
+
+
+
+public class ObservableOutputStream extends FilterOutputStream
+{
+    Set<StreamObserver> observers = new HashSet<StreamObserver>();
+    
+    
+    public ObservableOutputStream(OutputStream out)
+    {
+        super(out);
+    }
+
+    public void write(int b) throws IOException 
+    {
+        notifyListeners(b);
+        this.out.write(b);
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException 
+    {  
+        notifyListeners(b, off, len);
+        this.out.write(b, off, len);
+    }
+    public void addObserver (StreamObserver o)
+    {
+        synchronized (this.observers)
+        {
+            this.observers.add(o);
+        }
+    }
+    
+    public void addObservers (Collection<? extends StreamObserver> observers)
+    {
+        synchronized (this.observers)
+        {
+            this.observers.addAll(observers);
+        }
+    }
+    private void notifyListeners (byte[]b, int off, int len)
+    throws IOException
+    {
+        synchronized (this.observers)
+        {
+            for (StreamObserver o: this.observers)
+            {
+                try
+                {
+                  o.bytesReady(b, off, len);
+                }
+                catch( StreamObserverException e )
+                {
+                  throw new IOException(e.getMessage());
+                }
+            }
+        }
+    }
+
+    private void notifyListeners (int b)
+    throws IOException
+    {
+        synchronized (this.observers)
+        {
+            for (StreamObserver o: this.observers)
+            {
+                try
+                {
+                  o.byteReady(b);
+                }
+                catch( StreamObserverException e )
+                {
+                  throw new IOException(e.getMessage());
+                }
+            }
+        }
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableOutputStream.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/ObservableOutputStream.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/SecureSender.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/SecureSender.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/SecureSender.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/SecureSender.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,99 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client;
+
+import java.net.URI;
+import java.net.URL;
+
+import org.apache.maven.mercury.logging.IMercuryLogger;
+import org.apache.maven.mercury.logging.MercuryLoggerManager;
+import org.apache.maven.mercury.transport.api.Credentials;
+import org.apache.maven.mercury.transport.api.Server;
+import org.mortbay.jetty.client.Address;
+import org.mortbay.jetty.client.HttpClient;
+import org.mortbay.jetty.client.HttpDestination;
+import org.mortbay.jetty.client.HttpExchange;
+import org.mortbay.jetty.client.security.ProxyAuthorization;
+
+/**
+ * SecureSender
+ *
+ * Initiates a HttpExchange with the remote server, taking into account any proxy
+ * authentication required. Any non-proxy authentication required will be taken
+ * care of by the DestinationRealmResolver that is set on the HttpClient used
+ * by this class.
+ * 
+ * TODO think of a better name for this class.
+ */
+public class SecureSender
+{
+  private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( SecureSender.class );
+
+  public static void send (Server server, HttpClient httpClient, HttpExchange exchange)
+    throws Exception
+    {
+        if (server != null && server.hasProxy() && (server.getProxy() != null))
+        {
+            String s = exchange.getURI();
+            URI uri = new URI(s);
+            boolean ssl = "https".equalsIgnoreCase(uri.getScheme());
+            URL proxy = server.getProxy();
+
+            String host = proxy.getHost();
+            int port = proxy.getPort();
+            boolean proxySsl = "https".equalsIgnoreCase(proxy.getProtocol());
+            if (port < 0)
+            {
+                port = proxySsl?443:80;
+            }
+
+            Address proxyAddress = new Address(host,port);
+            HttpDestination destination = httpClient.getDestination(exchange.getAddress(), ssl);  
+            if( LOG.isDebugEnabled() )
+                LOG.debug("Matched destination "+destination);
+
+            destination.setProxy(proxyAddress);
+            if( LOG.isDebugEnabled() )
+                LOG.debug("Set proxy "+host+":"+port+" on destination");
+            LOG.info("Set proxy "+host+":"+port+" on destination");
+         
+            //set up authentication for the proxy
+            Credentials proxyCredentials = server.getProxyCredentials();
+
+            if (proxyCredentials != null)
+            {
+                if (proxyCredentials.isCertificate())
+                    throw new UnsupportedOperationException ("Proxy credential not supported");
+                else
+                {
+                    destination.setProxyAuthentication(new ProxyAuthorization (proxyCredentials.getUser(), proxyCredentials.getPass()));
+                    if( LOG.isDebugEnabled() )
+                        LOG.debug( "Set proxy authentication: "+proxyCredentials.getUser()+":"+proxyCredentials.getPass());
+                }
+            }
+            destination.send(exchange); 
+        }
+        else
+        { 
+            httpClient.send(exchange);
+        } 
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/SecureSender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/SecureSender.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/BatchIdGenerator.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/BatchIdGenerator.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/BatchIdGenerator.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/BatchIdGenerator.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+public interface BatchIdGenerator
+{
+    public String getId();
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/BatchIdGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/BatchIdGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployRequest.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployRequest.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployRequest.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployRequest.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,62 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.validate.Validator;
+import org.apache.maven.mercury.transport.api.Binding;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class DefaultDeployRequest
+implements DeployRequest
+{
+    private Set<Binding> _bindings = new HashSet<Binding>();
+    private boolean _failFast;
+    
+    public Set<Validator> getValidators()
+    {
+        return null;
+    }
+    public void setBindings(Set<Binding> bindings)
+    {
+        _bindings=bindings;
+    }
+    public Set<Binding> getBindings()
+    {
+        return _bindings;
+    }
+
+    public boolean isFailFast()
+    {
+        return _failFast;
+    }
+    
+    public void setFailFast (boolean f)
+    {
+        _failFast=f;
+    }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployRequest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployResponse.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployResponse.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployResponse.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployResponse.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,57 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+
+public class DefaultDeployResponse
+implements DeployResponse
+{
+    private Set<HttpClientException> _exceptions = Collections.synchronizedSet( new HashSet<HttpClientException>() );
+
+    public DefaultDeployResponse()
+    {
+    }
+
+    public void add( HttpClientException e )
+    {
+        _exceptions.add( e );
+    }
+
+    public Set<HttpClientException> getExceptions()
+    {
+        return _exceptions;
+    }
+
+    public String toString()
+    {
+        return _exceptions.toString();
+    }
+
+    public boolean hasExceptions()
+    {
+      return _exceptions != null && _exceptions.size() > 0;
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployResponse.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployer.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployer.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployer.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployer.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,385 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.maven.mercury.crypto.api.StreamObserver;
+import org.apache.maven.mercury.crypto.api.StreamObserverException;
+import org.apache.maven.mercury.crypto.api.StreamObserverFactory;
+import org.apache.maven.mercury.crypto.api.StreamVerifierFactory;
+import org.apache.maven.mercury.logging.IMercuryLogger;
+import org.apache.maven.mercury.logging.MercuryLoggerManager;
+import org.apache.maven.mercury.spi.http.client.DestinationRealmResolver;
+import org.apache.maven.mercury.spi.http.client.FileExchange;
+import org.apache.maven.mercury.spi.http.client.HandshakeExchange;
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+import org.apache.maven.mercury.transport.api.Binding;
+import org.apache.maven.mercury.transport.api.Server;
+import org.mortbay.jetty.HttpMethods;
+import org.mortbay.jetty.client.HttpClient;
+
+/**
+ * JettyDeployer
+ * <p/>
+ * Implementation of Deployer using Jetty async HttpClient.
+ */
+public class DefaultDeployer implements Deployer
+{
+    private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( DefaultDeployer.class );
+    
+    private HttpClient _httpClient;
+    private BatchIdGenerator _idGenerator;
+    private Set<Server> _servers = new HashSet<Server>();
+
+    public DefaultDeployer()
+        throws HttpClientException
+    {
+        _idGenerator = new RandomBatchIdGenerator();
+        _httpClient = new HttpClient();
+        _httpClient.setConnectorType( HttpClient.CONNECTOR_SELECT_CHANNEL );
+        _httpClient.registerListener( "org.mortbay.jetty.client.webdav.WebdavListener");
+        try
+        {
+            _httpClient.start();
+        }
+        catch ( Exception e )
+        {
+            throw new HttpClientException( null, "unable to start http client", e );
+        }
+    }
+
+    public DefaultDeployer( HttpClient client, BatchIdGenerator idGenerator )
+        throws HttpClientException
+    {
+        _idGenerator = idGenerator;
+        if ( _idGenerator == null )
+        {
+            throw new HttpClientException( null, "no id generator supplied" );
+        }
+
+        _httpClient = client;
+        try
+        {
+            if ( !_httpClient.isStarted() )
+            {
+                _httpClient.start();
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new HttpClientException( null, "unable to start http client", e );
+        }
+    }
+
+    public BatchIdGenerator getBatchIdGenerator()
+    {
+        return _idGenerator;
+    }
+
+    public HttpClient getHttpClient()
+    {
+        return _httpClient;
+    }
+    
+    public void setServers (Set<Server>servers)
+    {
+        _servers.clear();
+        _servers.addAll(servers);
+        _httpClient.setRealmResolver(new DestinationRealmResolver(_servers));
+    }
+    
+    public Set<Server> getServers()
+    {
+        return _servers;
+    }
+
+    /**
+     * Deploy a set files synchronously. This call will return when either all
+     * files have been successfully deployed, or one or more failures have
+     * occurred, depending on the failFast setting of the DeployRequest.
+     *
+     * @see org.apache.maven.mercury.spi.http.client.deploy.Deployer#deploy(org.apache.maven.mercury.spi.http.client.deploy.DeployRequest)
+     */
+    public DeployResponse deploy( DeployRequest request )
+    {
+        final DeployResponse[] response = new DeployResponse[]{null};
+
+        deploy( request, new DeployCallback()
+        {
+            public void onComplete( DeployResponse r )
+            {
+                synchronized ( response )
+                {
+                    response[0] = r;
+                    response.notify();
+                }
+            }
+        } );
+
+        synchronized ( response )
+        {
+            try
+            {
+                while ( response[0] == null )
+                {
+                    response.wait();
+                }
+            }
+            catch ( InterruptedException e )
+            {
+                return null;
+            }
+            return response[0];
+        }
+    }
+
+    /**
+     * Deploy a set of files, returning immediately. The callback will be called when
+     * all the files have been deployed or one or more errors occur (depends on the FailFast
+     * setting of the DeployRequest).
+     *
+     * @see org.apache.maven.mercury.spi.http.client.deploy.Deployer#deploy(org.apache.maven.mercury.spi.http.client.deploy.DeployRequest, org.apache.maven.mercury.spi.http.client.deploy.DeployCallback)
+     */
+    public void deploy( final DeployRequest request, final DeployCallback callback )
+    {
+        if ( request == null )
+        {
+            throw new IllegalArgumentException( "No request" );
+        }
+
+        if ( callback == null )
+        {
+            throw new IllegalArgumentException( "No callback" );
+        }
+
+        final String batchId = _idGenerator.getId();
+        final AtomicInteger count = new AtomicInteger( request.getBindings().size() );
+        final List<DeploymentTarget> targets = new ArrayList<DeploymentTarget>( request.getBindings().size() );
+        final DefaultDeployResponse response = new DefaultDeployResponse();
+        final Set<String> remoteHandshakeUrls = new HashSet<String>();
+
+        Binding[] bindings = new Binding[request.getBindings().size()];
+        request.getBindings().toArray( bindings );
+        for ( int i = 0; i < bindings.length && count.get() > 0; i++ )
+        {
+            final Binding binding = bindings[i];
+            DeploymentTarget target = null;
+            try
+            {
+                Server server = resolveServer(binding);
+                
+                Set<StreamObserver> observers = createStreamObservers( server, binding.isExempt() );
+                
+                target = new DeploymentTarget( server, _httpClient, batchId, binding, request.getValidators(), observers )
+                {
+                    public void onComplete()
+                    {
+                        if ( getRemoteJettyUrl() != null )
+                        {
+                            remoteHandshakeUrls.add( getRemoteJettyUrl() );
+                        }
+                        //uploaded the file - have we uploaded all of them?
+                        checkComplete( callback, batchId, count, request, response, remoteHandshakeUrls );
+                    }
+
+                    public void onError( HttpClientException exception )
+                    {
+                        if ( getRemoteJettyUrl() != null )
+                        {
+                            remoteHandshakeUrls.add( getRemoteJettyUrl() );
+                        }
+                        response.add( exception );
+                        checkComplete( callback, batchId, count, request, response, remoteHandshakeUrls );
+                    }
+                };
+                targets.add( target );
+            }
+            catch ( Exception e )
+            {
+                response.add( new HttpClientException( binding, e ) );
+                checkComplete( callback, batchId, count, request, response, remoteHandshakeUrls );
+            }
+        }
+
+        for ( final DeploymentTarget target : targets )
+        {
+            target.deploy(); //upload file
+        }
+    }
+
+    private synchronized void checkComplete( final DeployCallback callback,
+                                             String batchId,
+                                             AtomicInteger count,
+                                             DeployRequest request,
+                                             DeployResponse response,
+                                             Set<String> remoteHandshakeUrls )
+    {
+        int x = count.decrementAndGet();
+        boolean completor = x == 0;
+        if ( !completor && request.isFailFast() && response.getExceptions().size() > 0 )
+        {
+            completor = count.getAndSet( 0 ) > 0;
+        }
+
+        if ( completor )
+        {
+            commit( callback, response, batchId, remoteHandshakeUrls );
+        }
+    }
+
+    /**
+     * Send message to remote server (if Jetty) to indicate all
+     * files uploaded should now be commited or discarded if there were exceptions.
+     *
+     * @param batchId
+     */
+    private void commit( final DeployCallback callback,
+                         final DeployResponse response,
+                         final String batchId,
+                         final Set<String> remoteHandshakeUrls )
+    {
+        if ( remoteHandshakeUrls.isEmpty() )
+        {
+            callback.onComplete( response );
+        }
+        else
+        {
+            final AtomicInteger count = new AtomicInteger( remoteHandshakeUrls.size() );
+            Map<String, String> headers = new HashMap<String, String>();
+            //if no errors, then commit, otherwise send a discard message
+            if ( response.getExceptions().isEmpty() )
+            {
+                headers.put( FileExchange.__BATCH_COMMIT_HEADER, batchId );
+            }
+            else
+            {
+                headers.put( FileExchange.__BATCH_DISCARD_HEADER, batchId );
+            }
+            for ( final String remoteUrl : remoteHandshakeUrls )
+            {
+                HandshakeExchange exchange = new HandshakeExchange( _httpClient, HttpMethods.POST, remoteUrl, headers )
+                {
+                    public void onHandshakeComplete( String url )
+                    {
+                        checkHandshakeComplete( callback, response, count );
+
+                    }
+
+                    public void onHandshakeError( String url, Exception e )
+                    {
+                        response.getExceptions().add( new HttpClientException( null, e ) );
+                        checkHandshakeComplete( callback, response, count );
+                    }
+                };
+            }
+        }
+    }
+
+
+    private void checkHandshakeComplete( final DeployCallback callback,
+                                         final DeployResponse response,
+                                         AtomicInteger count )
+    {
+        boolean completor = count.decrementAndGet() == 0;
+        if ( completor )
+        {
+            callback.onComplete( response );
+        }
+    }
+ 
+    private Server resolveServer (Binding binding)
+    throws MalformedURLException
+    {
+        if (binding.getRemoteResource() == null)
+        return null;
+        
+        URL bindingURL = binding.getRemoteResource();
+        Iterator<Server> itor = _servers.iterator();
+        Server server = null;
+        while(itor.hasNext() && server==null)
+        {
+            Server s = itor.next();
+            if (bindingURL.getProtocol().equalsIgnoreCase(s.getURL().getProtocol()) 
+                    && bindingURL.getHost().equalsIgnoreCase(s.getURL().getHost())
+                    && bindingURL.getPort() == s.getURL().getPort())
+                server = s;
+        }
+        return server;
+    }
+    
+    private Set<StreamObserver> createStreamObservers( Server server, boolean exempt )
+    throws StreamObserverException
+    {
+        HashSet<StreamObserver> observers = new HashSet<StreamObserver>();
+        
+        if( server == null )
+          return observers;
+        
+        if( (!exempt) && server.hasWriterStreamVerifierFactories() )
+        {
+          Set<StreamVerifierFactory> factories = server.getWriterStreamVerifierFactories();
+          for (StreamVerifierFactory f:factories)
+          {
+              observers.add( f.newInstance() );
+          }
+        }
+        
+        if( server.hasWriterStreamObserverFactories() )
+        {
+          Set<StreamObserverFactory> factories = server.getWriterStreamObserverFactories();
+          for (StreamObserverFactory f:factories)
+          {
+              observers.add( f.newInstance() );
+          }
+        }
+        return observers;
+    }
+    
+    public void stop()
+    {
+        if( _httpClient == null )
+            return;
+        
+        if( _httpClient.isStopped() || _httpClient.isStopping() )
+            return;
+        
+        try
+        {
+            _httpClient.stop();
+        }
+        catch ( Exception e )
+        {
+            LOG.error( e.getMessage() );
+        }
+            
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DefaultDeployer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployCallback.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployCallback.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployCallback.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployCallback.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+/**
+ * DeployCallback
+ * <p/>
+ * Classes that implement this method will be notified when a given job has
+ * been completed and validated.
+ */
+public interface DeployCallback
+{
+    /**
+     * Callback for asynchronous version of Retriever.retrieve.
+     *
+     * @param response empty if all artifacts retrieved ok, list of exceptions otherwise
+     */
+    void onComplete( DeployResponse response );
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployCallback.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployRequest.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployRequest.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployRequest.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployRequest.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,40 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.validate.Validator;
+import org.apache.maven.mercury.transport.api.Binding;
+
+
+/**
+ * RetrievalRequest
+ * <p/>
+ * A set of files to retrieve from remote locations.
+ */
+public interface DeployRequest
+{
+    public abstract Set<Binding> getBindings();
+
+    public abstract boolean isFailFast();
+    
+    public Set<Validator> getValidators();
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployRequest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployResponse.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployResponse.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployResponse.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployResponse.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+
+/**
+ * DeployResponse
+ * <p/>
+ * A response to a request to upload a set of files to
+ * remote location(s).
+ */
+public interface DeployResponse
+{
+    /**
+     * The set will be empty if the operation completed successfully,
+     * or will contain a single entry if the Request is failFast, otherwise
+     * there will be one exception for every Binding in the Request.
+     *
+     * @return
+     */
+    public Set<HttpClientException> getExceptions();
+    
+    public boolean hasExceptions();
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeployResponse.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/Deployer.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/Deployer.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/Deployer.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/Deployer.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+/**
+ * Deployer
+ * <p/>
+ * Deploy a set of files to remote locations as an atomic operation.
+ */
+public interface Deployer
+{
+    /** Deploy a set of files and return when all done. */
+    DeployResponse deploy( DeployRequest request );
+
+
+    /**
+     * Deploy a set of files and return immediately without waiting.
+     * The callback will be called when files are ready or an error
+     * has occurred.
+     */
+    void deploy( DeployRequest request, DeployCallback callback );
+    
+    /**
+     * stop and release all resources
+     * @throws Exception 
+     */
+    void stop();
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/Deployer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/Deployer.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeploymentTarget.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeploymentTarget.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeploymentTarget.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeploymentTarget.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,335 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.mercury.crypto.api.StreamObserver;
+import org.apache.maven.mercury.crypto.api.StreamVerifier;
+import org.apache.maven.mercury.logging.IMercuryLogger;
+import org.apache.maven.mercury.logging.MercuryLoggerManager;
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+import org.apache.maven.mercury.spi.http.validate.Validator;
+import org.apache.maven.mercury.transport.api.Binding;
+import org.apache.maven.mercury.transport.api.Server;
+import org.mortbay.jetty.HttpHeaders;
+import org.mortbay.jetty.client.HttpClient;
+
+public abstract class DeploymentTarget
+{    
+    private static final IMercuryLogger log = MercuryLoggerManager.getLogger(DeploymentTarget.class);
+    protected Server _server;
+    protected HttpClient _httpClient;
+    protected String _batchId;
+    protected Binding _binding;
+    protected Set<Validator> _validators;
+    protected TargetState _targetState;
+    protected TargetState _checksumState;
+    protected HttpClientException _exception;
+    protected String _remoteJettyUrl;
+    protected Set<StreamObserver> _observers = new HashSet<StreamObserver>();
+    protected List<StreamVerifier> _verifiers = new ArrayList<StreamVerifier>();
+    protected int _checkSumFilesDeployed = -1; 
+
+    
+    public abstract void onComplete();
+
+    public abstract void onError( HttpClientException exception );
+
+
+    public class TargetState
+    {
+        public static final int __START_STATE = 1;
+        public static final int __REQUESTED_STATE = 2;
+        public static final int __READY_STATE = 3;
+
+        private int _state;
+        private Exception _exception;
+
+        public TargetState()
+        {
+            _state = __START_STATE;
+        }
+
+        public synchronized void ready()
+        {
+            setState( __READY_STATE );
+        }
+
+        public synchronized void ready( Exception e )
+        {
+            setState( __READY_STATE );
+            _exception = e;
+        }
+
+        public synchronized void requested()
+        {
+            setState( __REQUESTED_STATE );
+        }
+
+        public synchronized boolean isStart()
+        {
+            return _state == __START_STATE;
+        }
+
+        public synchronized boolean isRequested()
+        {
+            return _state == __REQUESTED_STATE;
+        }
+
+        public synchronized boolean isError()
+        {
+            return _exception != null;
+        }
+
+        public boolean isReady()
+        {
+            return _state == __READY_STATE;
+        }
+
+        public synchronized void setState( int status )
+        {
+            _state = status;
+        }
+
+        public synchronized int getState()
+        {
+            return _state;
+        }
+
+        public synchronized Exception getException()
+        {
+            return _exception;
+        }
+    }
+
+    public DeploymentTarget( Server server, HttpClient client, String batchId, Binding binding, Set<Validator> validators, Set<StreamObserver> observers )
+    {
+        _server = server;
+        _httpClient = client;
+        _batchId = batchId;
+        _binding = binding;
+        _validators = validators;
+        
+        for (StreamObserver o:observers)
+        {
+            if (StreamVerifier.class.isAssignableFrom(o.getClass()))
+                _verifiers.add((StreamVerifier)o);
+            _observers.add(o);
+        }
+      
+        if ( _binding == null )
+        {
+            throw new IllegalArgumentException( "Nothing to deploy - null binding" );
+        }
+        
+        if ( _binding.isFile() && (_binding.getLocalFile() == null || !_binding.getLocalFile().exists()) )
+        {
+            throw new IllegalArgumentException( "Nothing to deploy - local file not found: " + _binding.getLocalFile() );
+        }
+        if( _binding.isInMemory() && _binding.getLocalInputStream() == null )
+        {
+            throw new IllegalArgumentException( "Nothing to deploy - inMemory binding with null stream" );
+        }
+        _targetState = new TargetState();
+        _checksumState = new TargetState();
+        if (_verifiers.isEmpty())
+            _checksumState.ready();
+    }
+
+    public Binding getBinding()
+    {
+        return _binding;
+    }
+
+    public void deploy()
+    {
+        updateState( null );
+    }
+
+    private synchronized void updateState( Throwable t )
+    {
+  
+        if (log.isDebugEnabled())
+        {
+            log.debug("updateState: exception="+t+" targetState="+_targetState.getState()+" checksumState="+_checksumState.getState()+" verifiers="+_verifiers.size()+" checksumsdeployed="+_checkSumFilesDeployed);
+        }
+        if ( t != null && _exception == null )
+        {
+            _exception = ( t instanceof HttpClientException ? (HttpClientException) t : new HttpClientException( _binding, t ) );
+        }
+
+        if (_exception != null)
+        {
+            onError(_exception);
+        }
+        else
+        {
+            //if the target file can be uploaded, then upload it, calculating checksums on the fly as necessary
+            if ( _targetState.isStart() )
+            {
+                deployLocalFile();
+            }
+            //Upload the checksums
+            else if ( _targetState.isReady() && (_verifiers.size()>0) && (_checkSumFilesDeployed < (_verifiers.size() -1)) )
+            {
+                deployNextChecksumFile();
+            }
+            else if ( _targetState.isReady() && (_checksumState.isReady()))
+            {
+                onComplete();
+            }
+        }
+    }
+
+    private void deployLocalFile()
+    {
+        FilePutExchange fileExchange = new FilePutExchange( _server, _batchId, _binding, _binding.getLocalFile(), _observers, _httpClient )
+        {
+            public void onFileComplete( String url, File localFile )
+            {
+                
+                DeploymentTarget.this._remoteJettyUrl = getRemoteJettyUrl();
+                _targetState.ready();
+                updateState( null );
+            }
+
+            public void onFileError( String url, Exception e )
+            {
+                
+                DeploymentTarget.this._remoteJettyUrl = getRemoteJettyUrl();
+                _targetState.ready( e );
+                updateState( e );
+            }
+        };
+
+        if( _server != null && _server.hasUserAgent() )
+          fileExchange.setRequestHeader( HttpHeaders.USER_AGENT, _server.getUserAgent() );
+
+        _targetState.requested();
+        
+        fileExchange.send();
+    }
+
+
+    private void deployNextChecksumFile()
+    {
+        Binding binding = _binding;
+        File file = null;
+        StreamVerifier v =  _verifiers.get(++_checkSumFilesDeployed);
+
+        //No local checksum file, so make a temporary one using the checksum we 
+        //calculated as we uploaded the file
+        try
+        {
+            URL url = _binding.getRemoteResource();
+            if (url != null)
+            {
+                url = new URL( url.toString() + v.getAttributes().getExtension() );
+            }
+      
+            String localFileName = getFileName(url);
+            
+            file = File.createTempFile( localFileName, ".tmp" );
+            file.deleteOnExit();
+            OutputStreamWriter fw = new OutputStreamWriter( new FileOutputStream( file ), "UTF-8" );
+            fw.write( v.getSignature() );
+            fw.close();
+            binding = new Binding(url, file);
+        }
+        catch ( Exception e )
+        {
+            _checksumState.ready( e );
+        }
+
+
+        //upload the checksum file
+        Set<StreamObserver> emptySet = Collections.emptySet();
+        FilePutExchange checksumExchange = new FilePutExchange( _server, _batchId, binding, file, emptySet, _httpClient )
+        {
+            public void onFileComplete( String url, File localFile )
+            {      
+                DeploymentTarget.this._remoteJettyUrl = getRemoteJettyUrl();
+                if (_checkSumFilesDeployed == (_verifiers.size() - 1))
+                    _checksumState.ready();
+                updateState( null );
+            }
+
+            public void onFileError( String url, Exception e )
+            {             
+                DeploymentTarget.this._remoteJettyUrl = getRemoteJettyUrl();
+                if (_checkSumFilesDeployed == (_verifiers.size() - 1))
+                    _checksumState.ready( e );
+                updateState( e );
+            }
+        };
+
+        if( _server != null && _server.hasUserAgent() )
+          checksumExchange.setRequestHeader( HttpHeaders.USER_AGENT, _server.getUserAgent() );
+
+        _checksumState.requested();
+        checksumExchange.send();
+    }
+
+    public boolean isRemoteJetty()
+    {
+        return _remoteJettyUrl != null;
+    }
+
+    public String getRemoteJettyUrl()
+    {
+        return _remoteJettyUrl;
+    }
+
+    public synchronized boolean isComplete()
+    {
+        return ( _checksumState.isReady() && _targetState.isReady() );
+    }
+    
+    public String getFileName (URL url)
+    {
+        if (url==null)
+            return "";
+        String localFileName = url.getFile();
+        int i = localFileName.indexOf('?');
+        if (i > 0)
+            localFileName = localFileName.substring(0, i);
+        if (localFileName.endsWith("/"))
+            localFileName = localFileName.substring(0, localFileName.length()-1);
+        i = localFileName.lastIndexOf('/');
+        if (i >= 0)
+            localFileName = localFileName.substring(i+1);
+        return localFileName;
+    }
+
+    public String toString()
+    {
+        return "DeploymentTarget:" + _binding.getRemoteResource() + ":" + _targetState + ":" + _checksumState + ":" + isComplete();
+    }
+   
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeploymentTarget.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/DeploymentTarget.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/FilePutExchange.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/FilePutExchange.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/FilePutExchange.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/FilePutExchange.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,210 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.crypto.api.StreamObserver;
+import org.apache.maven.mercury.logging.IMercuryLogger;
+import org.apache.maven.mercury.logging.MercuryLoggerManager;
+import org.apache.maven.mercury.spi.http.client.FileExchange;
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+import org.apache.maven.mercury.spi.http.client.HttpServletResponse;
+import org.apache.maven.mercury.spi.http.client.ObservableInputStream;
+import org.apache.maven.mercury.transport.api.Binding;
+import org.apache.maven.mercury.transport.api.Server;
+import org.mortbay.io.Buffer;
+import org.mortbay.jetty.HttpMethods;
+import org.mortbay.jetty.client.HttpClient;
+
+
+/**
+ * FilePutExchange
+ * <p/>
+ * Asynchronously PUT a file to a remote server. The file that is being uploaded can also
+ * have it's SHA-1 digest calculated as it is being streamed up.
+ */
+public abstract class FilePutExchange extends FileExchange
+{
+    private static final int __readLimit = 1024;
+    private static final IMercuryLogger log = MercuryLoggerManager.getLogger(FilePutExchange.class);
+    private String _batchId;
+    private InputStream _inputStream;
+    private String _remoteRepoUrl;
+    private String _remoteBatchId;
+    private Set<StreamObserver> _observers = new HashSet<StreamObserver>();
+    
+    public abstract void onFileComplete( String url, File localFile );
+
+    public abstract void onFileError( String url, Exception e );
+
+
+    public FilePutExchange( Server server, String batchId, Binding binding, File localFile, Set<StreamObserver> observers, HttpClient client )
+    {
+        super( server, binding, localFile, client );
+        
+        _batchId = batchId;
+        
+        if( observers != null && ! observers.isEmpty() )
+            _observers.addAll(observers);
+    }
+
+
+    /**
+     * Start the upload. Ensure that the id of the mercury is set as a request header
+     * so all files part of the same mercury can be identified as an atomic unit.
+     */
+    public void send()
+    {
+        try
+        {
+            setMethod( HttpMethods.PUT );
+            setRequestHeader( "Content-Type", "application/octet-stream" );
+            if (_binding.isFile())
+            {
+                setRequestHeader( "Content-Length", String.valueOf( _localFile.length() ) );
+                if (log.isDebugEnabled())
+                    log.debug("PUT of "+_localFile.length()+" bytes");
+                
+                for (StreamObserver o: _observers)
+                    o.setLength(_localFile.length());
+            }
+
+            if (log.isDebugEnabled())
+                log.debug("PUT: "+getURI());
+            
+            setRequestContentSource( getInputStream() );
+            setRequestHeader( __BATCH_HEADER, _batchId );            
+            super.send();
+        }
+        catch ( Exception e )
+        {
+            onFileError( _url, e );
+        }
+    }
+
+    public boolean isRemoteJetty()
+    {
+        return _remoteRepoUrl != null;
+    }
+
+    public String getRemoteJettyUrl()
+    {
+        return _remoteRepoUrl;
+    }
+
+
+    protected void onResponseHeader( Buffer name, Buffer value )
+    {
+        if ( name.toString().equalsIgnoreCase( __BATCH_SUPPORTED_HEADER ) )
+        {
+            _remoteRepoUrl = value.toString();
+        }
+        else if ( name.toString().equalsIgnoreCase( __BATCH_HEADER ) )
+        {
+            _remoteBatchId = value.toString();
+        }
+    }
+
+    protected void onResponseComplete()
+    {
+        try
+        {
+            if (_inputStream != null)
+                _inputStream.close();
+            
+            if ( _status != HttpServletResponse.SC_OK && _status != HttpServletResponse.SC_CREATED && _status != HttpServletResponse.SC_NO_CONTENT )
+            {
+                onFileError( _url, new HttpClientException( _binding, "Http status code=" + _status ) );
+                return;
+            }
+
+            if ( _remoteBatchId != null && !_batchId.equals( _remoteBatchId ) )
+            {
+                onFileError( _url, new HttpClientException( _binding,
+                    "Non matching mercury ids. Sent=" + _batchId + " received=" + _remoteBatchId ) );
+                return;
+            }
+
+            //we've uploaded the file
+            onFileComplete( _url, _localFile );
+        }
+        catch ( Exception e )
+        {
+            onFileError( _url, new HttpClientException( _binding, e.getLocalizedMessage() ) );
+        }
+    }
+
+
+    private InputStream getInputStream()
+        throws IOException
+    {
+        if ( _inputStream == null )
+        {
+            InputStream is = null;
+            if (_binding.isFile())
+                is = new FileInputStream( _localFile );
+            else if (_binding.isInMemory())
+            {
+                is = _binding.getLocalInputStream();
+                if (!getRetryStatus())
+                {                 
+                    if (is.markSupported())
+                        is.mark(__readLimit);
+                }
+                else
+                {
+                    if (is.markSupported())
+                        is.reset();
+                }
+            }
+
+            //if this request is being retried, then don't set up the observers a second
+            //time?
+            if (!getRetryStatus())
+            {
+                ObservableInputStream ois = new ObservableInputStream( is );
+                _inputStream = ois;
+                ois.addObservers(_observers);
+            }
+            else
+                _inputStream = is;
+        }    
+        return _inputStream;
+    }
+
+   
+    protected void onRetry() throws IOException
+    {
+        super.onRetry();
+        if (_inputStream != null)
+            _inputStream.close();
+        
+        _inputStream = null;
+        setRequestContent(null);
+        setRequestContentSource(getInputStream());
+    }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/FilePutExchange.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/FilePutExchange.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/RandomBatchIdGenerator.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/RandomBatchIdGenerator.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/RandomBatchIdGenerator.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/RandomBatchIdGenerator.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.deploy;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Random;
+
+
+public class RandomBatchIdGenerator implements BatchIdGenerator
+{
+    protected final static String SESSION_ID_RANDOM_ALGORITHM = "SHA1PRNG";
+    private Random _random;
+    private boolean _initialized;
+
+
+    public RandomBatchIdGenerator()
+    {
+    }
+
+    public String getId()
+    {
+        init();
+        String id = "";
+        if ( !( _random instanceof SecureRandom ) )
+        {
+            id = String.valueOf( hashCode() ^ Runtime.getRuntime().freeMemory() ^ _random.nextInt() );
+        }
+        else
+        {
+            id = String.valueOf( _random.nextLong() );
+        }
+        return id;
+    }
+
+    public void setRandom( Random random )
+    {
+        _random = random;
+    }
+
+    public Random getRandom()
+    {
+        return _random;
+    }
+
+    private void init()
+    {
+        synchronized ( this )
+        {
+            if ( !_initialized )
+            {
+                try
+                {
+                    _random = SecureRandom.getInstance( SESSION_ID_RANDOM_ALGORITHM );
+                }
+                catch ( NoSuchAlgorithmException e )
+                {
+                    _random = new Random();
+                }
+                _random.setSeed(
+                    _random.nextLong() ^ System.currentTimeMillis() ^ hashCode() ^ Runtime.getRuntime().freeMemory() );
+                _initialized = true;
+            }
+        }
+    }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/RandomBatchIdGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/deploy/RandomBatchIdGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalRequest.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalRequest.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalRequest.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalRequest.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.retrieve;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.validate.Validator;
+import org.apache.maven.mercury.transport.api.Binding;
+
+public class DefaultRetrievalRequest implements RetrievalRequest
+{
+    private boolean _isFailFast;
+    private Set<Binding> _bindings;
+    private Set<Validator> _validators;
+    
+    public void setFailFast(boolean failFast)
+    {
+        _isFailFast = failFast;
+    }
+
+    public boolean isFailFast()
+    {
+        return _isFailFast;
+    }
+    
+    public RetrievalRequest addBinding( Binding binding )
+    {
+        if ( _bindings == null )
+        {
+            _bindings = new HashSet<Binding>();
+        }
+        
+        _bindings.add( binding );
+        
+        return this;
+    }
+    
+    public void setBindings(Set<Binding> bindings)
+    {
+        _bindings = new HashSet<Binding>(bindings);
+    }
+    
+    public Set<Binding> getBindings()
+    {
+        return _bindings;
+    }
+
+    public void setValidators(Set<Validator> validators)
+    {
+        _validators = new HashSet<Validator>(validators);
+    }
+    
+    public Set<Validator> getValidators()
+    {
+        return _validators;
+    }
+    
+    public String toString()
+    {
+        return _bindings.toString()+"|"+_isFailFast;
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalRequest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalRequest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalResponse.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalResponse.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalResponse.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalResponse.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file                                                                                            
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.mercury.spi.http.client.retrieve;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+
+public class DefaultRetrievalResponse implements RetrievalResponse
+{
+    private Set<HttpClientException> _exceptions = Collections.synchronizedSet( new HashSet<HttpClientException>() );
+
+    public DefaultRetrievalResponse()
+    {
+    }
+
+    protected void add( HttpClientException exception )
+    {
+        _exceptions.add( exception );
+    }
+
+    public Set<HttpClientException> getExceptions()
+    {
+        return _exceptions;
+    }
+
+    public String toString()
+    {
+        return _exceptions.toString();
+    }
+    
+    public boolean hasExceptions()
+    {
+        return _exceptions.size() > 0;
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalResponse.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/DefaultRetrievalResponse.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision