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 2008/08/02 00:55:48 UTC
svn commit: r681887 [7/10] - in /maven/sandbox/trunk/mercury:
mercury-artifact/ mercury-artifact/src/ mercury-artifact/src/main/
mercury-artifact/src/main/java/ mercury-artifact/src/main/java/org/
mercury-artifact/src/main/java/org/apache/ mercury-arti...
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/FileGetExchange.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/FileGetExchange.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/FileGetExchange.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/FileGetExchange.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,151 @@
+/**
+ * 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.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletResponse;
+
+
+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.ObservableOutputStream;
+import org.apache.maven.mercury.transport.api.Binding;
+import org.apache.maven.mercury.transport.api.StreamObserver;
+import org.mortbay.io.Buffer;
+import org.mortbay.jetty.HttpMethods;
+import org.mortbay.jetty.client.HttpClient;
+
+
+/**
+ * FileGetExchange
+ * <p/>
+ * Make an asynchronous request to download a file and stream its bytes to a file.
+ * When all bytes have been received onFileComplete will be called.
+ * <p/>
+ * As an optimization, the file that is being downloaded can have it's
+ * SHA-1 digest calculated as it is being streamed down.
+ */
+public abstract class FileGetExchange extends FileExchange
+{
+ private OutputStream _outputStream;
+ private Set<StreamObserver> _observers = new HashSet<StreamObserver>();
+
+ /**
+ * Constructor.
+ *
+ * @param binding the remote file to fetch
+ * @param localFile the local file location to store the remote file
+ * @param observers observers of the io stream
+ * @param client async http client
+ */
+ public FileGetExchange( Binding binding, File localFile, Set<StreamObserver> observers, HttpClient client )
+ {
+ super( binding, localFile, client );
+ _observers.addAll(observers);
+ }
+
+
+ /** Start the retrieval. */
+ public void send()
+ {
+ setMethod( HttpMethods.GET );
+ super.send();
+ }
+
+
+ protected void onResponseComplete()
+ {
+ //All bytes of file have been received
+ try
+ {
+ if ( _status == HttpServletResponse.SC_NOT_FOUND )
+ {
+ onFileError( _url, new FileNotFoundException( "File not found on remote server" ) );
+ return;
+ }
+ else if ( _status != HttpServletResponse.SC_OK )
+ {
+ onFileError( _url, new Exception( "Http status code=" + _status ) );
+ return;
+ }
+
+ onFileComplete( _url, _localFile );
+ }
+ catch ( Exception e )
+ {
+ onFileError( _url, new HttpClientException( _binding, e.getLocalizedMessage() ) );
+ }
+ }
+
+
+ /**
+ * Stream the downloaded bytes to a file
+ *
+ * @see org.mortbay.jetty.client.HttpExchange$ContentExchange#onResponseContent(org.sonatype.io.Buffer)
+ */
+ protected void onResponseContent( Buffer content )
+ throws IOException
+ {
+ try
+ {
+ OutputStream os = getOutputStream();
+ content.writeTo( os );
+ }
+ catch ( NoSuchAlgorithmException e )
+ {
+ throw new IOException( e.getLocalizedMessage() );
+ }
+ }
+
+
+ /**
+ * Get an output stream for the file contents. A digest can be optionally calculated
+ * for the file contents as they are being streamed.
+ *
+ * @return OutputStream for file contents
+ * @throws IOException if io error occurs
+ * @throws NoSuchAlgorithmException if the SHA-1 algorithm is not supported
+ */
+ protected OutputStream getOutputStream()
+ throws IOException, NoSuchAlgorithmException
+ {
+ if ( _outputStream == null )
+ {
+ OutputStream os = null;
+ if (_binding.isFile())
+ os = new FileOutputStream( _localFile );
+ else if (_binding.isInMemory())
+ os = _binding.getLocalOutputStream();
+
+ ObservableOutputStream oos = new ObservableOutputStream( os );
+ oos.addObservers(_observers);
+ _outputStream = oos;
+ }
+ return _outputStream;
+ }
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalCallback.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalCallback.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalCallback.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalCallback.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,34 @@
+/**
+ * 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;
+
+/**
+ * Classes that implement this method will be notified when a given job has
+ * been completed and validated.
+ */
+public interface RetrievalCallback
+{
+ /**
+ * Callback for asynchronous version of Retriever.retrieve.
+ *
+ * @param response empty if all artifacts retrieved ok, list of exceptions otherwise
+ */
+ public abstract void onComplete( RetrievalResponse response );
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalRequest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalRequest.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalRequest.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalRequest.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,42 @@
+/**
+ * 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.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
+ * and a set of validators to apply to them.
+ */
+public interface RetrievalRequest
+{
+ Set<Binding> getBindings();
+
+ boolean isFailFast();
+
+ Set<Validator> getValidators();
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalResponse.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalResponse.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalResponse.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalResponse.java Fri Aug 1 15:55:40 2008
@@ -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.retrieve;
+
+import java.util.Set;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+
+
+/**
+ * RetrievalResponse
+ * <p/>
+ * Response from a request to download a set of files.
+ */
+public interface RetrievalResponse
+{
+ /**
+ * 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
+ */
+ Set<HttpClientException> getExceptions();
+
+ boolean hasExceptions();
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalTarget.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalTarget.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalTarget.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/RetrievalTarget.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,450 @@
+/**
+ * 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.io.File;
+import java.io.IOException;
+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 javax.servlet.http.HttpServletResponse;
+
+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.validate.Validator;
+import org.apache.maven.mercury.transport.api.Binding;
+import org.apache.maven.mercury.transport.api.StreamObserver;
+import org.apache.maven.mercury.transport.api.Verifier;
+import org.mortbay.jetty.client.HttpExchange;
+
+
+/**
+ * RetrievalTarget
+ * <p/>
+ * A RetrievalTarget is a remote file that must be downloaded locally, checksummed
+ * and then atomically moved to its final location. The RetrievalTarget encapsulates
+ * the temporary local file to which the remote file is downloaded, and also the
+ * retrieval of the checksum file(s) and the checksum calculation(s).
+ */
+public abstract class RetrievalTarget
+{
+ public static final String __PREFIX = "JTY_";
+ public static final String __TEMP_SUFFIX = ".tmp";
+ public static final int __START_STATE = 1;
+ public static final int __REQUESTED_STATE = 2;
+ public static final int __READY_STATE = 3;
+
+ protected int _checksumState;
+ protected int _targetState;
+
+ protected HttpClientException _exception;
+ protected Binding _binding;
+ protected File _tempFile;
+ protected DefaultRetriever _retriever;
+ protected boolean _complete;
+ protected HttpExchange _exchange;
+ protected Set<Validator> _validators;
+ protected Set<StreamObserver> _observers = new HashSet<StreamObserver>();
+ protected List<Verifier> _verifiers = new ArrayList<Verifier>();
+ protected Map<Verifier, String> _verifierMap = new HashMap<Verifier, String>();
+
+
+ public abstract void onComplete();
+
+ public abstract void onError( HttpClientException exception );
+
+ /**
+ * Constructor
+ *
+ * @param binding
+ * @param callback
+ */
+ public RetrievalTarget( DefaultRetriever retriever, Binding binding, Set<Validator> validators, Set<StreamObserver> observers )
+ {
+ if ( binding == null ||
+ (binding.getRemoteResource() == null) ||
+ (binding.isFile() && (binding.getLocalFile() == null)) ||
+ (binding.isInMemory() && (binding.getLocalOutputStream() == null)))
+ {
+ throw new IllegalArgumentException( "Nothing to retrieve" );
+ }
+ _retriever = retriever;
+ _binding = binding;
+ _validators = validators;
+
+ //sift out the potential checksum verifiers
+ for (StreamObserver o: observers)
+ {
+ if (Verifier.class.isAssignableFrom(o.getClass()))
+ _verifiers.add((Verifier)o);
+ else
+ _observers.add(o);
+ }
+
+ if (_binding.isFile())
+ {
+ _tempFile = new File( _binding.getLocalFile().getParentFile(),
+ __PREFIX + _binding.getLocalFile().getName() + __TEMP_SUFFIX );
+ _tempFile.deleteOnExit();
+ if ( !_tempFile.getParentFile().exists() )
+ {
+ _tempFile.getParentFile().mkdirs();
+ }
+
+ if ( _tempFile.exists() )
+ {
+ onError( new HttpClientException( binding, "File exists " + _tempFile.getAbsolutePath() ) );
+ }
+ else if ( !_tempFile.getParentFile().canWrite() )
+ {
+ onError( new HttpClientException( binding,
+ "Unable to write to dir " + _tempFile.getParentFile().getAbsolutePath() ) );
+ }
+ }
+ }
+
+
+
+ public File getTempFile()
+ {
+ return _tempFile;
+ }
+
+ public String getUrl()
+ {
+ return _binding.getRemoteResource().toExternalForm();
+ }
+
+
+ /** Start by getting the appropriate checksums */
+ public void retrieve()
+ {
+ //if there are no checksum verifiers configured, proceed directly to get the file
+ if (_verifiers.size() == 0)
+ {
+ _checksumState = __READY_STATE;
+ updateTargetState(__START_STATE, null);
+ }
+ else
+ {
+ _checksumState = __START_STATE;
+ updateChecksumState(-1, null);
+ }
+ }
+
+
+ /** Move the temporary file to its final location */
+ public boolean move()
+ {
+ if (_binding.isFile())
+ return _tempFile.renameTo( _binding.getLocalFile() );
+ else
+ return true;
+ }
+
+ /** Cleanup temp files */
+ public synchronized void cleanup()
+ {
+ deleteTempFile();
+ if ( _exchange != null )
+ {
+ _exchange.cancel();
+ }
+ }
+
+ public synchronized boolean isComplete()
+ {
+ return _complete;
+ }
+
+ public String toString()
+ {
+ return "T:" + _binding.getRemoteResource() + ":" + _targetState + ":" + _checksumState + ":" + _complete;
+ }
+
+ private void updateChecksumState (int index, Throwable ex)
+ {
+ if ( _exception == null && ex != null )
+ {
+ if ( ex instanceof HttpClientException )
+ {
+ _exception = (HttpClientException) ex;
+ }
+ else
+ {
+ _exception = new HttpClientException( _binding, ex );
+ }
+ }
+
+ if (ex != null)
+ {
+ _checksumState = __READY_STATE;
+ onError(_exception);
+ }
+ else
+ {
+ boolean proceedWithTargetFile = false;
+ if (index >= 0)
+ {
+ //check if the just-completed retrieval means that we can stop trying to download checksums
+ Verifier v = _verifiers.get(index);
+ if (_verifierMap.containsKey(v) && v.isSufficient())
+ proceedWithTargetFile = true;
+ }
+
+ index++;
+
+ if ((index < _verifiers.size()) && !proceedWithTargetFile)
+ {
+ retrieveChecksum(index);
+ }
+ else
+ {
+ _checksumState = __READY_STATE;
+
+ //finished retrieving all possible checksums. Add all verifiers
+ //that had matching checksums into the observers list
+ _observers.addAll(_verifierMap.keySet());
+
+ //now get the file now we have the checksum sorted out
+ updateTargetState( __START_STATE, null );
+ }
+ }
+ }
+
+
+
+
+
+ /**
+ * Check the actual checksum against the expected checksum
+ *
+ * @return
+ */
+ public boolean verifyChecksum()
+ {
+ boolean ok = true;
+
+ synchronized (_verifierMap)
+ {
+ Iterator<Map.Entry<Verifier, String>> itor = _verifierMap.entrySet().iterator();
+ while (itor.hasNext() && ok)
+ {
+ Map.Entry<Verifier, String> e = itor.next();
+ ok = e.getKey().verifySignature(e.getValue());
+ }
+ }
+
+ return ok;
+ }
+
+
+
+ public boolean validate( List<String> errors )
+ {
+ if ( _validators == null || _validators.isEmpty() )
+ {
+ return true;
+ }
+
+ String ext = _binding.getRemoteResource().toString();
+ if (ext.endsWith("/"))
+ ext = ext.substring(0, ext.length()-1);
+
+ int i = ext.lastIndexOf( "." );
+ ext = ( i > 0 ? ext.substring( i + 1 ) : "" );
+
+ for ( Validator v : _validators )
+ {
+ String vExt = v.getFileExtension();
+ if ( vExt.equalsIgnoreCase( ext ) )
+ {
+ try
+ {
+ if (_binding.isFile())
+ {
+ if ( !v.validate( _tempFile.getCanonicalPath(), errors ) )
+ {
+ return false;
+ }
+ }
+ else if (_binding.isInMemory())
+ {
+ //TODO ????
+ //v.validate(_binding.getInboundContent())
+ }
+ }
+ catch ( IOException e )
+ {
+ errors.add( e.getMessage() );
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+
+
+ protected synchronized void updateTargetState( int state, Throwable ex )
+ {
+ _targetState = state;
+ if ( _exception == null && ex != null )
+ {
+ if ( ex instanceof HttpClientException )
+ {
+ _exception = (HttpClientException) ex;
+ }
+ else
+ {
+ _exception = new HttpClientException( _binding, ex );
+ }
+ }
+
+ if ( _targetState == __START_STATE )
+ {
+ _exchange = retrieveTargetFile();
+ }
+
+ //if both checksum and target file are ready, we're ready to return callback
+ if (_targetState == __READY_STATE )
+ {
+ _complete = true;
+ if ( _exception == null )
+ {
+ onComplete();
+ }
+ else
+ {
+ onError( _exception );
+ }
+ }
+ }
+
+ /** Asynchronously fetch the checksum for the target file. */
+ private HttpExchange retrieveChecksum(final int index)
+ {
+ HttpExchange exchange = new HttpExchange.ContentExchange()
+ {
+ protected void onException( Throwable ex )
+ {
+ //if the checksum is mandatory, then propagate the exception and stop processing
+ if (!_verifiers.get(index).isLenient())
+ {
+ updateChecksumState(index, ex);
+ }
+ else
+ updateChecksumState(index, null);
+
+ }
+
+ protected void onResponseComplete() throws IOException
+ {
+ super.onResponseComplete();
+ Verifier v = _verifiers.get(index);
+
+ if ( getResponseStatus() == HttpServletResponse.SC_OK )
+ {
+ //We got a checksum so match it up with the verifier it is for
+ synchronized (_verifierMap)
+ {
+ if (v.isSufficient())
+ _verifierMap.clear(); //remove all other entries, we only need one checksum
+ _verifierMap.put(v, getResponseContent().trim());
+ }
+ updateChecksumState(index, null);
+ }
+ else
+ {
+ if (!v.isLenient())
+ {
+ //checksum file MUST be present, fail
+ updateChecksumState(index, new Exception ("Mandatory checksum file not found "+this.getURI()));
+ }
+ else
+ updateChecksumState(index, null);
+ }
+ }
+ };
+
+ exchange.setURL( getChecksumFileURLAsString( _verifiers.get(index)) );
+
+ try
+ {
+ _retriever.getHttpClient().send( exchange );
+ }
+ catch ( IOException ex )
+ {
+ updateChecksumState(index, ex);
+ }
+ return exchange;
+ }
+
+
+ /** Asynchronously fetch the target file. */
+ private HttpExchange retrieveTargetFile()
+ {
+ updateTargetState( __REQUESTED_STATE, null );
+
+ //get the file, calculating the digest for it on the fly
+ FileExchange exchange = new FileGetExchange( _binding, getTempFile(), _observers, _retriever.getHttpClient() )
+ {
+ public void onFileComplete( String url, File localFile )
+ {
+ //we got the target file ok, so tell our main callback
+ _targetState = __READY_STATE;
+ updateTargetState( __READY_STATE, null );
+ }
+
+ public void onFileError( String url, Exception e )
+ {
+ //an error occurred whilst fetching the file, return an error
+ _targetState = __READY_STATE;
+ updateTargetState( __READY_STATE, e );
+ }
+ };
+ exchange.send();
+ return exchange;
+ }
+
+ private String getChecksumFileURLAsString (Verifier verifier)
+ {
+ String extension = verifier.getExtension();
+ if (extension.charAt(0) != '.')
+ extension = "."+extension;
+ return _binding.getRemoteResource().toString() + extension;
+ }
+
+ private boolean deleteTempFile()
+ {
+ if ( _tempFile != null && _tempFile.exists() )
+ {
+ return _tempFile.delete();
+ }
+ return false;
+ }
+
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/Retriever.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/Retriever.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/Retriever.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/client/retrieve/Retriever.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,51 @@
+/**
+ * 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;
+
+/**
+ * Retriever
+ * <p/>
+ * Component to retrieve a set of remote files as an atomic operation.
+ */
+public interface Retriever
+{
+ /**
+ * Retrieve a set of artifacts and wait until all retrieved successfully
+ * or an error occurs.
+ * <p/>
+ * Note: whilst this method is synchronous for the caller, the implementation
+ * will be asynchronous so many artifacts are fetched in parallel.
+ *
+ * @param request
+ * @return
+ */
+ RetrievalResponse retrieve( RetrievalRequest request );
+
+
+ /**
+ * Retrieve a set of artifacts without waiting for the results.
+ * When all results have been obtained (or an error occurs) the
+ * RetrievalResponse will be called.
+ *
+ * @param request
+ * @param callback
+ */
+ void retrieve( RetrievalRequest request, RetrievalCallback callback );
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/BatchFilter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/BatchFilter.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/BatchFilter.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/BatchFilter.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,452 @@
+/**
+ * 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.server;
+
+import org.mortbay.jetty.HttpMethods;
+import org.mortbay.servlet.PutFilter;
+import org.mortbay.util.IO;
+import org.mortbay.util.URIUtil;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * BatchFilter
+ * <p/>
+ * Base class for handling atomic uploads of batches of files.
+ * Subclasses should implement their own means of making the
+ * uploads atomic. The methods putFile, commitFiles, discardFiles
+ * can be overridden/implemented in order to facilitate this.
+ * For example, the DefaultBatchFilter subclass copies all files
+ * to a staging area before moving them to their final locations
+ * upon receipt of a Jetty-Batch-Commit message.
+ * <p/>
+ * TODO consider having a scavenger thread to remove failed or incomplete uploads?
+ *
+ * @see org.sonatype.mercury.server.jetty.DefaultBatchFilter
+ */
+public abstract class BatchFilter extends PutFilter
+{
+ protected ConcurrentMap<String, Batch> _batches = new ConcurrentHashMap<String, Batch>();
+ protected String _batchIdHeader = "Jetty-Batch-Id";
+ protected String _batchSupportedHeader = "Jetty-Batch-Supported";
+ protected String _batchCommitHeader = "Jetty-Batch-Commit";
+ protected String _batchDiscardHeader = "Jetty-Batch-Discard";
+
+ /**
+ * Batch
+ * <p/>
+ * Retains the status of a mercury. If a mercury succeeds it is removed
+ * from the list. If it fails, then it is retained in the list
+ * but marked as failed. If a mercury is not completed, then the
+ * timestamp can be used by a timer thread to clean up.
+ */
+ protected class Batch
+ {
+ protected String _batchId;
+ protected long _timestamp;
+ protected boolean _ok;
+ protected List<String> _files;
+
+
+ public Batch( String batchId, long timestamp )
+ {
+ _batchId = batchId;
+ _timestamp = timestamp;
+ _files = new ArrayList<String>();
+ }
+
+ public String getBatchId()
+ {
+ return _batchId;
+ }
+
+ public void addFile( String file )
+ {
+ _files.add( file );
+ }
+
+ public List getFiles()
+ {
+ return _files;
+ }
+
+ public void failed()
+ {
+ _ok = false;
+ }
+
+ public boolean isOK()
+ {
+ return _ok;
+ }
+
+ public long getTimestamp()
+ {
+ return _timestamp;
+ }
+
+ public String toString()
+ {
+ return "BatchStatus: id=" + _batchId + " ts=" + _timestamp + " count=" + _files.size() + ", " + _ok;
+ }
+ }
+
+ /**
+ * Implement this method to finish the upload of the files by making them
+ * available for download. When this method returns, all files forming part of
+ * the mercury should be available.
+ *
+ * @param request
+ * @param response
+ * @param batchId
+ * @return
+ * @throws Exception
+ */
+ public abstract boolean commitFiles( HttpServletRequest request, HttpServletResponse response, Batch batch )
+ throws Exception;
+
+ /**
+ * Implement this method to abort the upload of a mercury of files. When this method returns,
+ * none of the files forming part of the upload should be available for download.
+ *
+ * @param request
+ * @param response
+ * @param batchId
+ * @return
+ * @throws Exception
+ */
+ public abstract boolean discardFiles( HttpServletRequest request, HttpServletResponse response, Batch batch )
+ throws Exception;
+
+
+ /**
+ * Initialize the filter. Read all configurable parameters.
+ *
+ * @see org.sonatype.servlet.PutFilter#init(javax.servlet.FilterConfig)
+ */
+ public void init( FilterConfig config )
+ throws ServletException
+ {
+ super.init( config );
+
+ //allow name of headers to be exchanged to be configured
+ String s = config.getInitParameter( "batchIdHeader" );
+ if ( s != null )
+ {
+ _batchIdHeader = s;
+ }
+ s = config.getInitParameter( "batchSupportedHeader" );
+ if ( s != null )
+ {
+ _batchSupportedHeader = s;
+ }
+ s = config.getInitParameter( "batchCommitHeader" );
+ if ( s != null )
+ {
+ _batchCommitHeader = s;
+ }
+ s = config.getInitParameter( "batchDiscardHeader" );
+ if ( s != null )
+ {
+ _batchDiscardHeader = s;
+ }
+ }
+
+
+ /**
+ * Run the filter.
+ *
+ * @see org.sonatype.servlet.PutFilter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
+ */
+ public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain )
+ throws IOException, ServletException
+ {
+ HttpServletRequest request = (HttpServletRequest) req;
+ HttpServletResponse response = (HttpServletResponse) res;
+
+ //if GET fall through to filter chain
+ if ( request.getMethod().equals( HttpMethods.GET ) )
+ {
+ chain.doFilter( req, res );
+ return;
+ }
+
+
+ String batchId = request.getHeader( _batchIdHeader );
+ String commitId = request.getHeader( _batchCommitHeader );
+ String discardId = request.getHeader( _batchDiscardHeader );
+
+ //System.err.println("method="+request.getMethod()+" batchid="+batchId+" commitId="+commitId+" discardId="+discardId);
+
+ //we can't do atomic batches, handle as a normal PUT
+ if ( batchId == null && commitId == null && discardId == null )
+ {
+ System.err.println( "Not a batching request, doing PutFilter instead" );
+ super.doFilter( req, res, chain );
+ return;
+ }
+
+ /* TODO Is it worth handling this situation? This would mean that a directory was sent as the url
+ * along with a batchId. The cost is that the pathContext would be calculated twice in this case.
+
+ if (pathInContext.endsWith("/"))
+ {
+ super.doFilter(req,res,chain);
+ return;
+ }
+ */
+
+ if ( batchId != null )
+ {
+ handlePut( request, response, batchId );
+ return;
+ }
+
+ if ( discardId != null )
+ {
+ handleDiscard( request, response, discardId );
+ return;
+ }
+
+ if ( commitId != null )
+ {
+ handleCommit( request, response, commitId );
+ return;
+ }
+
+ //otherwise - shouldn't get here
+ chain.doFilter( req, res );
+ }
+
+ /**
+ * Handle a PUT request.
+ * <p/>
+ * The batchId is saved to a list of currently active batchIds so that
+ * all files forming part of the mercury can be committed or discarded as a
+ * whole later on.
+ * <p/>
+ * If a file already exists, then status 200 is returned; if the file
+ * did not previously exist, then status 201 is returned, otherwise
+ * a 403 is returned.
+ *
+ * @param request
+ * @param response
+ * @param batchId
+ * @throws ServletException
+ * @throws IOException
+ */
+ public void handlePut( HttpServletRequest request, HttpServletResponse response, String batchId )
+ throws ServletException, IOException
+ {
+ String servletPath = request.getServletPath();
+ String pathInfo = request.getPathInfo();
+ String pathInContext = URIUtil.addPaths( servletPath, pathInfo );
+ String finalResource = URIUtil.addPaths( _baseURI, pathInContext );
+ File finalFile = null;
+ try
+ {
+ finalFile = new File( new URI( finalResource ) );
+ boolean exists = finalFile.exists();
+
+ putFile( request, response, pathInContext, batchId );
+
+ Batch batch = addBatch( batchId, finalResource );
+
+ String contextPath = _context.getContextPath();
+ if ( contextPath.equals( "" ) )
+ {
+ contextPath = "/";
+ }
+ if ( !contextPath.endsWith( "/" ) )
+ {
+ contextPath += "/";
+ }
+ String commitBatchUrl = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + contextPath;
+ response.setHeader( _batchSupportedHeader, commitBatchUrl );
+ response.setStatus( exists ? HttpServletResponse.SC_OK : HttpServletResponse.SC_CREATED );
+ response.flushBuffer();
+ }
+ catch ( Exception ex )
+ {
+ _context.log( ex.toString(), ex );
+ response.sendError( HttpServletResponse.SC_FORBIDDEN );
+ }
+ }
+
+ /**
+ * Client side wants us to discard all files in mercury.
+ *
+ * @param request
+ * @param response
+ * @param batchId
+ * @throws ServletException
+ * @throws IOException
+ */
+ public void handleDiscard( HttpServletRequest request, HttpServletResponse response, String batchId )
+ throws ServletException, IOException
+ {
+ boolean ok = true;
+ try
+ {
+ ok = discardFiles( request, response, _batches.get( batchId ) );
+ response.setStatus( ( ok ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR ) );
+ response.flushBuffer();
+ }
+ catch ( Exception ex )
+ {
+ _context.log( ex.toString(), ex );
+ response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+ }
+ finally
+ {
+ updateBatch( batchId, ok );
+ }
+ }
+
+
+ /**
+ * Client side wants us to move files into final position.
+ *
+ * @param request
+ * @param response
+ * @param batchId
+ * @throws ServletException
+ * @throws IOException
+ */
+ public void handleCommit( HttpServletRequest request, HttpServletResponse response, String batchId )
+ throws ServletException, IOException
+ {
+ boolean ok = true;
+ try
+ {
+ ok = commitFiles( request, response, _batches.get( batchId ) );
+ response.setStatus( ( ok ? HttpServletResponse.SC_OK : HttpServletResponse.SC_INTERNAL_SERVER_ERROR ) );
+ response.flushBuffer();
+ }
+ catch ( Exception ex )
+ {
+ _context.log( ex.toString(), ex );
+ response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
+ }
+ finally
+ {
+ updateBatch( batchId, ok );
+ }
+ }
+
+ /**
+ * Default behaviour is to put the file directly to it's final location.
+ * <p/>
+ * Subclasses can choose to override this method and put the file
+ * into a staging area first.
+ *
+ * @param request
+ * @param response
+ * @param pathInContext
+ * @param batchId
+ * @throws Exception
+ * @see org.sonatype.mercury.server.jetty.DefaultBatchFilter
+ */
+ public void putFile( HttpServletRequest request,
+ HttpServletResponse response,
+ String pathInContext,
+ String batchId )
+ throws Exception
+ {
+ String finalResource = URIUtil.addPaths( _baseURI, pathInContext );
+ File finalFile = null;
+ finalFile = new File( new URI( finalResource ) );
+ File parent = finalFile.getParentFile();
+ parent.mkdirs();
+ int toRead = request.getContentLength();
+ InputStream in = request.getInputStream();
+ OutputStream out = new FileOutputStream( finalFile, false );
+ if ( toRead >= 0 )
+ {
+ IO.copy( in, out, toRead );
+ }
+ else
+ {
+ IO.copy( in, out );
+ }
+
+ }
+
+ /**
+ * Remember a mercury, or update the count of files in the mercury.
+ *
+ * @param batchId
+ */
+ protected Batch addBatch( String batchId, String file )
+ {
+ Batch status = (Batch) _batches.get( batchId );
+ long timestamp = System.currentTimeMillis();
+ if ( status == null )
+ {
+ status = new Batch( batchId, timestamp );
+ _batches.put( batchId, status );
+ }
+ status.addFile( file );
+ return status;
+ }
+
+
+ /**
+ * Update the status of the mercury.
+ *
+ * @param batchId
+ * @param ok if true, the mercury job is removed from the list; otherwise it is marked as failed
+ */
+ protected void updateBatch( String batchId, boolean ok )
+ {
+ Batch status = (Batch) _batches.get( batchId );
+ if ( status == null )
+ {
+ _context.log( "Unknown mercury id to update: " + batchId );
+ }
+ else
+ {
+ if ( ok )
+ {
+ _batches.remove( batchId );
+ }
+ else
+ {
+ status.failed(); //mark as failed
+ }
+ }
+ }
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/StagingBatchFilter.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/StagingBatchFilter.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/StagingBatchFilter.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/server/StagingBatchFilter.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,229 @@
+/**
+ * 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.server;
+
+import org.mortbay.util.IO;
+import org.mortbay.util.URIUtil;
+
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+
+
+/**
+ * DefaultBatchFilter
+ * <p/>
+ * Handles the atomic upload (using PUT messages) of a batch of files. "Atomic" means
+ * that either all file uploads succeed or none do. This transactionality can only be
+ * guaranteed when using the mercury client, as a "commit/discard" message
+ * is sent from the client side to indicate how to terminate the mercury operation. If
+ * a commit is received, then all files that form part of the batch - indicated by a
+ * batch id in the PUT headers - are moved from a staging location to the final
+ * location. If a discard is received, then all files forming part of the mercury will
+ * be deleted. If the client side is not the jetty batcher, then the server side
+ * cannot know when the batch has ended, and therefore will immediately copy files
+ * to their final locations during the PUT.
+ */
+public class StagingBatchFilter extends BatchFilter
+{
+ private String _stagingDirURI;
+
+ public void init( FilterConfig config )
+ throws ServletException
+ {
+ super.init( config );
+
+ //allow tmp dir location to be configured
+ String t = config.getInitParameter( "stagingDirURI" );
+ if ( t != null )
+ {
+ _stagingDirURI = t;
+ }
+ else
+ {
+ //fall back to WEB-INF/lib
+ File f = new File( _context.getRealPath( "/" ) );
+ File w = new File( f, "WEB-INF" );
+ File l = new File( w, "lib" );
+ _stagingDirURI = l.toURI().toString();
+ }
+ }
+
+
+ /**
+ * Put the file to a staging area before doing move to final location
+ * on a commit.
+ *
+ * @see BatchFilter#putFile(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String, java.lang.String)
+ */
+ public void putFile( HttpServletRequest request,
+ HttpServletResponse response,
+ String pathInContext,
+ String batchId )
+ throws Exception
+ {
+ String stagedResource = URIUtil.addPaths( _stagingDirURI,
+ batchId ); //put the file into staging dir under the batchid
+ stagedResource = URIUtil.addPaths( stagedResource, pathInContext );
+ File stagedFile = null;
+
+ try
+ {
+ stagedFile = new File( new URI( stagedResource ) );
+ File parent = stagedFile.getParentFile();
+ parent.mkdirs();
+
+ int toRead = request.getContentLength();
+ InputStream in = request.getInputStream();
+ OutputStream out = new FileOutputStream( stagedFile, false );
+ if ( toRead >= 0 )
+ {
+ IO.copy( in, out, toRead );
+ }
+ else
+ {
+ IO.copy( in, out );
+ }
+ out.close();
+ }
+ catch ( Exception e )
+ {
+ try
+ {
+ if ( stagedFile.exists() )
+ {
+ stagedFile.delete();
+ }
+ throw e;
+ }
+ catch ( Exception ex )
+ {
+ _context.log( ex.toString(), ex );
+ }
+ }
+ }
+
+
+ /**
+ * Do the move of all files in mercury to a final location
+ *
+ * @see BatchFilter#commitFiles(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
+ */
+ public boolean commitFiles( HttpServletRequest request, HttpServletResponse response, Batch batch )
+ throws Exception
+ {
+ if ( batch == null )
+ {
+ return true; //nothing to do
+ }
+
+ boolean ok = true;
+ String stagedResource = URIUtil.addPaths( _stagingDirURI, batch.getBatchId() );
+ File batchDir = new File( new URI( stagedResource ) );
+ File[] files = batchDir.listFiles();
+ for ( int i = 0; files != null && i < files.length; i++ )
+ {
+ String name = files[i].getName();
+ File dest = new File( new URI( URIUtil.addPaths( _baseURI, name ) ) );
+ if ( !files[i].renameTo( dest ) )
+ {
+ ok = false;
+ }
+ }
+ if ( ok )
+ {
+ ok = batchDir.delete();
+ }
+ return ok;
+ }
+
+
+ /**
+ * Delete all files in the mercury from the staging area.
+ *
+ * @see BatchFilter#discardFiles(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.String)
+ */
+ public boolean discardFiles( HttpServletRequest request, HttpServletResponse response, Batch batch )
+ throws Exception
+ {
+ if ( batch == null )
+ {
+ return true; //nothing to do
+ }
+
+ String stagedResource = URIUtil.addPaths( _stagingDirURI, batch.getBatchId() );
+ File batchDir = new File( new URI( stagedResource ) );
+ boolean ok = true;
+ if ( !deleteFile( batchDir ) )
+ {
+ ok = false;
+ }
+ return ok;
+ }
+
+
+ /**
+ * Recursively descend file hierarchy and delete all files.
+ *
+ * @param f
+ * @return
+ */
+ private boolean deleteFile( File f )
+ {
+
+ if ( f == null )
+ {
+ return true;
+ }
+ if ( f.isFile() )
+ {
+ return f.delete();
+ }
+ else if ( f.isDirectory() )
+ {
+ File[] files = f.listFiles();
+ boolean ok = true;
+ for ( int i = 0; files != null && i < files.length; i++ )
+ {
+ if ( !deleteFile( files[i] ) )
+ {
+ ok = false;
+ }
+ }
+
+ if ( !f.delete() )
+ {
+ ok = false;
+ }
+
+ return ok;
+ }
+ else
+ {
+ return true;
+ }
+ }
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/PomValidator.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/PomValidator.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/PomValidator.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/PomValidator.java Fri Aug 1 15:55:40 2008
@@ -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.validate;
+
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.IOException;
+import java.util.List;
+
+public class PomValidator implements Validator
+{
+ public String getFileExtension()
+ {
+ return "pom";
+ }
+
+ public boolean validate(String stagedFile, List<String> errors)
+ {
+ try
+ {
+ String file = FileUtils.fileRead( stagedFile );
+
+ if ( file.contains( "<project>" ) )
+ {
+ return true;
+ }
+ else
+ {
+ errors.add( "file not valid" );
+ }
+ }
+ catch ( IOException ioe )
+ {
+ errors.add( "ioe" );
+ }
+
+ return false;
+ }
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/Validator.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/Validator.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/Validator.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/spi/http/validate/Validator.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,47 @@
+/**
+ * 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.validate;
+
+import java.util.List;
+
+/**
+ * Validator
+ * <p/>
+ * Interface for validating mercury content prior to completion
+ */
+public interface Validator
+{
+ /**
+ * The file extension the validator will process
+ *
+ * @return String file extension
+ */
+ public String getFileExtension();
+
+ /**
+ * validation for a given file target with errors being able to be logged in the list
+ *
+ * @param stagedFile
+ * @param errors
+ * @return true if target file is valid
+ */
+ public boolean validate( String stagedFile, List<String> errors );
+
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/ChecksumCalculator.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/ChecksumCalculator.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/ChecksumCalculator.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/ChecksumCalculator.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,43 @@
+/**
+ * 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.transport;
+
+
+
+public class ChecksumCalculator
+{
+ private static final byte[] __HEX_DIGITS = "0123456789abcdef".getBytes();
+
+
+ public static String encodeToAsciiHex( byte[] bytes )
+ {
+ int l = bytes.length;
+
+ byte[] raw = new byte[l * 2];
+
+ for ( int i = 0, j = 0; i < l; i++ )
+ {
+ raw[j++] = __HEX_DIGITS[( 0xF0 & bytes[i] ) >>> 4];
+ raw[j++] = __HEX_DIGITS[0x0F & bytes[i]];
+ }
+
+ return new String( raw );
+ }
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1Verifier.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1Verifier.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1Verifier.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1Verifier.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,113 @@
+/**
+ * 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.transport;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.maven.mercury.transport.api.Verifier;
+
+/**
+ * SHA1Verifier
+ *
+ *
+ */
+public class SHA1Verifier implements Verifier
+{
+ public static final String digestAlgorithm = "SHA-1";
+ private MessageDigest digest;
+ private byte[] digestBytes;
+ private boolean isLenient;
+ private boolean isSufficient;
+
+
+ public SHA1Verifier (boolean isLenient, boolean isSufficient)
+ {
+ this.isLenient = isLenient;
+ this.isSufficient = isSufficient;
+ try
+ {
+ digest = MessageDigest.getInstance( digestAlgorithm );
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ //TODO
+ }
+ }
+
+ public String getExtension()
+ {
+ return ".sha1";
+ }
+
+ public byte[] getSignatureBytes ()
+ {
+ if (digestBytes == null)
+ digestBytes = digest.digest();
+ return digestBytes;
+ }
+
+ public String getSignature()
+ {
+ return ChecksumCalculator.encodeToAsciiHex( getSignatureBytes() );
+ }
+
+ public void setLenient (boolean lenient)
+ {
+ isLenient = lenient;
+ }
+
+ public boolean isLenient()
+ {
+ return isLenient;
+ }
+
+ public void setSufficient (boolean sufficient)
+ {
+ isSufficient = sufficient;
+ }
+ public boolean isSufficient()
+ {
+ return isSufficient;
+ }
+
+ public boolean verifySignature(String sig)
+ {
+ String calculatedSignature = getSignature();
+ if (calculatedSignature == null && sig == null)
+ return true;
+ if ((calculatedSignature != null) && calculatedSignature.equals(sig))
+ return true;
+ return false;
+ }
+
+ public void byteReady(int b)
+ {
+ if (digest != null)
+ digest.update((byte)b);
+ }
+
+ public void bytesReady(byte[] b, int off, int len)
+ {
+ if (digest != null)
+ digest.update(b, off, len);
+ }
+
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1VerifierFactory.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1VerifierFactory.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1VerifierFactory.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/SHA1VerifierFactory.java Fri Aug 1 15:55:40 2008
@@ -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.transport;
+
+import org.apache.maven.mercury.transport.api.StreamObserver;
+import org.apache.maven.mercury.transport.api.StreamObserverFactory;
+
+public class SHA1VerifierFactory implements StreamObserverFactory
+{
+ private boolean isLenient;
+ private boolean isSufficient;
+
+ public SHA1VerifierFactory (boolean isLenient, boolean isSufficient)
+ {
+ this.isLenient = isLenient;
+ this.isSufficient = isSufficient;
+ }
+ public StreamObserver newInstance()
+ {
+ return new SHA1Verifier(this.isLenient, this.isSufficient);
+ }
+
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java Fri Aug 1 15:55:40 2008
@@ -0,0 +1,70 @@
+package org.apache.maven.mercury.transport.http;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+import org.apache.maven.mercury.spi.http.client.retrieve.DefaultRetrievalRequest;
+import org.apache.maven.mercury.spi.http.client.retrieve.DefaultRetriever;
+import org.apache.maven.mercury.spi.http.client.retrieve.RetrievalRequest;
+import org.apache.maven.mercury.spi.http.client.retrieve.RetrievalResponse;
+import org.apache.maven.mercury.transport.api.AbstractTransport;
+import org.apache.maven.mercury.transport.api.Binding;
+import org.apache.maven.mercury.transport.api.ReaderTransport;
+import org.apache.maven.mercury.transport.api.TransportException;
+import org.apache.maven.mercury.transport.api.TransportTransaction;
+import org.codehaus.plexus.i18n.DefaultLanguage;
+import org.codehaus.plexus.i18n.Language;
+
+/**
+ * Jetty client adaptor to ReaderTransport APIs
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class HttpReaderTransport
+extends AbstractTransport
+implements ReaderTransport
+{
+ private static final Language _lang = new DefaultLanguage( HttpReaderTransport.class );
+ private static final org.slf4j.Logger _log = org.slf4j.LoggerFactory.getLogger( HttpReaderTransport.class );
+
+ DefaultRetriever _httpReader;
+
+ /**
+ *
+ */
+ public HttpReaderTransport()
+ throws TransportException
+ {
+ try
+ {
+ _httpReader = new DefaultRetriever();
+ }
+ catch( HttpClientException e )
+ {
+ throw new TransportException(e);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.maven.mercury.transport.api.ReaderTransport#read(org.apache.maven.mercury.transport.api.TransportTransaction)
+ */
+ public TransportTransaction read( TransportTransaction trx )
+ throws TransportException
+ {
+ if( trx == null )
+ {
+ _log.error( _lang.getMessage( "empty.transaction", trx == null ? "null" : trx.toString() ) );
+ return trx;
+ }
+
+ DefaultRetrievalRequest request = new DefaultRetrievalRequest();
+
+ for( Binding b : trx.getBindings() )
+ request.addBinding( b );
+
+ RetrievalResponse response = _httpReader.retrieve( request );
+
+ return trx;
+ }
+
+}
Added: maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties?rev=681887&view=auto
==============================================================================
--- maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties (added)
+++ maven/sandbox/trunk/mercury/mercury-transport/mercury-transport-http/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties Fri Aug 1 15:55:40 2008
@@ -0,0 +1 @@
+empty.transaction=cannot serve empty transaction {0}, returning it back
\ No newline at end of file