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 [15/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/transport/api/TransportTransaction.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/TransportTransaction.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/TransportTransaction.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/TransportTransaction.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,153 @@
+/**
+ *  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.api;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Repository access transaction. Consists of a collection of bindings
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class TransportTransaction
+{
+  public static final int DEFAULT_SIZE = 32;
+  
+  protected Collection<Binding> _bindings;
+  
+  //------------------------------------------------------------------------------------------------
+  private void init()
+  {
+    init( DEFAULT_SIZE );
+  }
+  //------------------------------------------------------------------------------------------------
+  private void init( int n )
+  {
+    if( _bindings == null )
+      _bindings = new ArrayList<Binding>( n );
+  }
+  //------------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  public TransportTransaction()
+  {
+    init();
+  }
+  //------------------------------------------------------------------------------------------------
+  /**
+   * 
+   */
+  public TransportTransaction add( Binding binding )
+  {
+    init();
+    
+    _bindings.add( binding );
+    
+    return this;
+  }
+  //------------------------------------------------------------------------------------------------
+  public TransportTransaction add( URL remoteResource, File localResource )
+  {
+    init();
+    
+    _bindings.add( new Binding( remoteResource, localResource ) );
+    
+    return this;
+  }
+  //------------------------------------------------------------------------------------------------
+  public TransportTransaction add( URL remoteResource )
+  {
+    init();
+    
+    _bindings.add( new Binding( remoteResource ) );
+    
+    return this;
+  }
+  //------------------------------------------------------------------------------------------------
+  public TransportTransaction add( URL remoteResource, InputStream is )
+  {
+    init();
+    
+    _bindings.add( new Binding( remoteResource, is ) );
+    
+    return this;
+  }
+
+  //------------------------------------------------------------------------------------------------
+  public TransportTransaction add( URL remoteResource, byte [] localResource )
+  {
+    init();
+    
+    _bindings.add( new Binding( remoteResource, new ByteArrayInputStream(localResource)) );
+    
+    return this;
+  }
+  //------------------------------------------------------------------------------------------------
+  @SuppressWarnings("unchecked")
+  public Collection<Binding> getBindings()
+  {
+    return _bindings == null ? (List<Binding>)Collections.EMPTY_LIST : _bindings;
+  }
+
+  public void setBindings( List<Binding> bindings )
+  {
+    this._bindings = bindings;
+  }
+  //------------------------------------------------------------------------------------------------
+  public boolean isEmpty()
+  {
+    if( _bindings == null || _bindings.size() < 1 )
+      return true;
+    
+    return false;
+  }
+  //------------------------------------------------------------------------------------------------
+  public boolean hasErrors()
+  {
+    if( _bindings == null )
+      return false;
+    
+    for( Binding b : _bindings )
+      if( b.getError() != null )
+        return true;
+    
+    return false;
+  }
+  //------------------------------------------------------------------------------------------------
+  public void clearErrors()
+  {
+    if( _bindings == null )
+      return;
+    
+    for( Binding b : _bindings )
+      b.setError( null );
+  }
+  //------------------------------------------------------------------------------------------------
+  //------------------------------------------------------------------------------------------------
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/TransportTransaction.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/TransportTransaction.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/WriterTransport.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/WriterTransport.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/WriterTransport.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/WriterTransport.java Wed Apr 22 22:56:48 2009
@@ -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.transport.api;
+
+/**
+ * generic Transport interface - allows client to write data to a remote repository
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public interface WriterTransport
+extends Initializable
+{
+  public TransportTransaction write( TransportTransaction trx )
+  throws TransportException;
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/WriterTransport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/api/WriterTransport.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpReaderTransport.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,61 @@
+/**
+ *  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.http;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+import org.apache.maven.mercury.spi.http.client.retrieve.DefaultRetriever;
+import org.apache.maven.mercury.transport.api.AbstractTransport;
+import org.apache.maven.mercury.transport.api.InitializationException;
+import org.apache.maven.mercury.transport.api.ReaderTransport;
+import org.apache.maven.mercury.transport.api.TransportException;
+import org.apache.maven.mercury.transport.api.TransportTransaction;
+
+/**
+ * HTTP retriever adaptor: adopts DefaultRetriever to ReaderTransport API
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class HttpReaderTransport
+extends AbstractTransport
+implements ReaderTransport
+{
+  private DefaultRetriever _retriever;
+  
+  public TransportTransaction read( TransportTransaction trx )
+  throws TransportException
+  {
+    return null;
+  }
+
+  public void init()
+  throws InitializationException
+  {
+    try
+    {
+      _retriever = new DefaultRetriever();
+    }
+    catch( HttpClientException e )
+    {
+      throw new InitializationException(e);
+    }
+  }
+
+}

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

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

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpWriterTransport.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpWriterTransport.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpWriterTransport.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/HttpWriterTransport.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,66 @@
+/**
+ *  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.http;
+
+import org.apache.maven.mercury.spi.http.client.HttpClientException;
+import org.apache.maven.mercury.spi.http.client.deploy.DefaultDeployRequest;
+import org.apache.maven.mercury.spi.http.client.deploy.DefaultDeployer;
+import org.apache.maven.mercury.transport.api.AbstractTransport;
+import org.apache.maven.mercury.transport.api.InitializationException;
+import org.apache.maven.mercury.transport.api.TransportException;
+import org.apache.maven.mercury.transport.api.TransportTransaction;
+import org.apache.maven.mercury.transport.api.WriterTransport;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class HttpWriterTransport
+extends AbstractTransport
+implements WriterTransport
+{
+  
+  DefaultDeployer _deployer;
+
+  public TransportTransaction write( TransportTransaction trx )
+  throws TransportException
+  {
+    DefaultDeployRequest req = new DefaultDeployRequest();
+//    req.setBindings( trx.getBindings() );
+    
+    return null;
+  }
+
+  public void init()
+  throws InitializationException
+  {
+    try
+    {
+      _deployer = new DefaultDeployer();
+    }
+    catch( HttpClientException e )
+    {
+      throw new InitializationException(e);
+    }
+  }
+
+}

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

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

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties Wed Apr 22 22:56:48 2009
@@ -0,0 +1,19 @@
+#
+#  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.
+#
+empty.transaction=cannot serve empty transaction {0}, returning it back
\ No newline at end of file

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/transport/http/Messages.properties
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/DefaultMonitor.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/DefaultMonitor.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/DefaultMonitor.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/DefaultMonitor.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.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public class DefaultMonitor
+    implements Monitor
+{
+    Writer _writer;
+    boolean _timestamp = true;
+    private static final SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    
+
+    public DefaultMonitor( boolean timestamp )
+    {
+        this( System.out );
+        this._timestamp = timestamp;
+    }
+
+    public DefaultMonitor()
+    {
+        this( System.out );
+    }
+
+    public DefaultMonitor( OutputStream os )
+    {
+        _writer = new OutputStreamWriter( os );
+    }
+
+    public DefaultMonitor( Writer writer )
+    {
+        _writer = writer;
+    }
+
+    public void message( String msg )
+    {
+        try
+        {
+            if ( _writer != null )
+            {
+                if( _timestamp )
+                {
+                    _writer.write( fmt.format( new Date() ) );
+                    _writer.write( ": " );
+                }
+                _writer.write( msg );
+                _writer.write( "\n" );
+                _writer.flush();
+            }
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+        }
+    }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/DefaultMonitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/DefaultMonitor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileLockBundle.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileLockBundle.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileLockBundle.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileLockBundle.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,84 @@
+/**
+ *  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.util;
+
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class FileLockBundle
+{
+  String dir;
+  FileChannel channel;
+  FileLock lock;
+  
+  boolean fileLock = false;
+  
+  /**
+   * @param dir
+   * @param channel
+   * @param lock
+   */
+  public FileLockBundle(
+                  String dir,
+                  FileChannel channel,
+                  FileLock lock
+                      )
+  {
+    this.dir = dir;
+    this.channel = channel;
+    this.lock = lock;
+  }
+
+  /**
+   * @param dir
+   * @param channel
+   * @param lock
+   */
+  public FileLockBundle( String dir )
+  {
+    this.dir = dir;
+    this.fileLock = true;
+  }
+  
+  public void release()
+  {
+    if( lock == null )
+    {
+      if( fileLock  )
+        FileUtil.unlockDir( dir );
+
+      return;
+    }
+    
+    try
+    {
+      lock.release();
+      channel.close();
+    }
+    catch( IOException any ){}
+  }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileLockBundle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileLockBundle.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtil.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtil.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtil.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtil.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,1084 @@
+/**
+ *  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.util;
+
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionBuilder;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.maven.mercury.crypto.api.StreamObserverException;
+import org.apache.maven.mercury.crypto.api.StreamObserverFactory;
+import org.apache.maven.mercury.crypto.api.StreamVerifier;
+import org.apache.maven.mercury.crypto.api.StreamVerifierAttributes;
+import org.apache.maven.mercury.crypto.api.StreamVerifierException;
+import org.apache.maven.mercury.crypto.api.StreamVerifierFactory;
+import org.apache.maven.mercury.crypto.pgp.PgpStreamVerifierFactory;
+import org.apache.maven.mercury.crypto.sha.SHA1VerifierFactory;
+import org.apache.maven.mercury.logging.IMercuryLogger;
+import org.apache.maven.mercury.logging.MercuryLoggerManager;
+import org.codehaus.plexus.lang.DefaultLanguage;
+import org.codehaus.plexus.lang.Language;
+
+/**
+ * File related utilities: copy, write, sign, verify, etc.
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class FileUtil
+{
+  public static final String SEP = "/";
+  public static final char   SEP_CHAR = SEP.charAt( 0 );
+
+  public static final String DASH = "-";
+  public static final char   DASH_CHAR = DASH.charAt( 0 );
+
+  public static final String LOCK_FILE = ".lock";
+  public static final String DEFAULT_CHARSET = "utf-8";
+
+  public static final int    K = 1024;
+  public static final int    DEFAULT_BUFFER_SIZE = 10 * K;
+  
+  public static final String PROTOCOL_DELIM = "://";
+  public static final int    PROTOCOL_DELIM_LEN = PROTOCOL_DELIM.length();
+  public static final String [] URL_PROTOCOLS = new String [] {"http","https","dav","file","davs","webdav","webdavs","dav+http","dav+https"};
+  public static final String [] LOCAL_PROTOCOLS = new String [] {"file"};
+  //---------------------------------------------------------------------------------------------------------------
+  private static final IMercuryLogger LOG = MercuryLoggerManager.getLogger( FileUtil.class );
+  private static final Language LANG = new DefaultLanguage( FileUtil.class );
+
+  private static final OverlappingFileLockException FILE_LOCKED = new OverlappingFileLockException();
+  //---------------------------------------------------------------------------------------------------------------
+  public static void delete( File f )
+  {
+    if( ! f.exists()  )
+      return;
+
+    if( f.isDirectory() )
+    {
+      File [] kids = f.listFiles();
+      for( File kid : kids )
+        delete( kid );
+    }
+
+    f.delete();
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void copy( File fromFile, File toFile, boolean clean )
+  throws IOException
+  {
+    if( toFile.exists() && clean )
+      delete( toFile );
+
+    if( fromFile.isFile() )
+    {
+      copyFile( fromFile, toFile );
+      return;
+    }
+
+    File [] kids = fromFile.listFiles();
+    if( kids != null )
+    {
+      for( File kid : kids )
+      {
+        if( kid.isDirectory() )
+        {
+          File newDir = new File( toFile, kid.getName() );
+          newDir.mkdirs();
+
+          copy( kid, newDir, false );
+        }
+        else
+          copyFile( kid, toFile );
+      }
+    }
+
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  private static void copyFile( File f, File toFile )
+  throws IOException
+  {
+    File fOut = null;
+    
+    if( toFile.isDirectory() )
+      fOut = new File(toFile, f.getName() );
+    else
+      fOut = toFile;
+    
+    FileInputStream fis = new FileInputStream(f);
+    
+    writeRawData( fis, fOut );
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  /**
+   * Read the content of a file and converts it with UTF-8 encoding to a String.
+   */
+  public static String readRawDataAsString( File file )
+  throws IOException
+  {
+    return new String( readRawData( file ), DEFAULT_CHARSET );
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static byte[] readRawData( File file )
+  throws IOException
+  {
+    if( ! file.exists() )
+      return null;
+
+    FileInputStream fis = null;
+
+    try
+    {
+      fis = new FileInputStream( file );
+      int len = (int)file.length();
+      if( len == 0 )
+      {
+        LOG.info( LANG.getMessage( "reading.empty.file", file.getAbsolutePath() ) );
+        return null;
+      }
+
+      byte [] pom = new byte [ len ];
+      while( fis.available() < 1 )
+        try { Thread.sleep( 8L ); } catch( InterruptedException e ){}
+
+      fis.read( pom, 0, len );
+
+      return pom;
+    }
+    catch( IOException e )
+    {
+      throw  e;
+    }
+    finally
+    {
+      if( fis != null ) try { fis.close(); } catch( Exception any ) {}
+    }
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static byte[] readRawData( File file, Collection<StreamVerifierFactory> vFacs  )
+  throws IOException, FileUtilException, StreamVerifierException
+  {
+    if( file == null || ! file.exists() )
+      return null;
+
+    boolean verify = vFacs != null && vFacs.size() > 0;
+
+    String fileName = file.getAbsolutePath();
+
+    HashSet<StreamVerifier> vs = new HashSet<StreamVerifier>( verify ? vFacs.size() : 1 );
+
+    for( StreamVerifierFactory svf : vFacs )
+    {
+      StreamVerifier sv = svf.newInstance();
+      String ext = sv.getAttributes().getExtension();
+      String sigFileName = fileName + ( ext.startsWith( "." ) ? "" : "." ) + ext;
+      File sigFile = new File( sigFileName );
+      if( sigFile.exists() )
+      {
+        try
+        {
+          sv.initSignature( FileUtil.readRawDataAsString( sigFile ) );
+        }
+        catch( IOException e )
+        {
+          throw new FileUtilException( LANG.getMessage( "cannot.read.signature.file", sigFileName, e.getMessage() ) );
+        }
+        vs.add( sv );
+      }
+      else if( ! sv.getAttributes().isLenient() )
+      {
+        throw new FileUtilException( LANG.getMessage( "no.signature.file", ext, sigFileName ) );
+      }
+      // otherwise ignore absence of signature file, if verifier is lenient
+    }
+
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+    FileInputStream fin = null;
+    try
+    {
+      fin = new FileInputStream( file );
+      byte [] buf = new byte[ DEFAULT_BUFFER_SIZE ];
+      int n = -1;
+      while( (n = fin.read( buf )) != -1 )
+      {
+        if( verify )
+        {
+          for( StreamVerifier sv : vs )
+            try
+            {
+              sv.bytesReady( buf, 0, n );
+            }
+            catch( StreamObserverException e )
+            {
+              if( ! sv.getAttributes().isLenient() )
+                throw new FileUtilException(e);
+            }
+        }
+
+        baos.write( buf, 0, n );
+      }
+
+      if( verify )
+      {
+        for( StreamVerifier sv : vs )
+        {
+          if( sv.verifySignature() )
+          {
+            if( sv.getAttributes().isSufficient() )
+              break;
+          }
+          else
+          {
+            if( !sv.getAttributes().isLenient() )
+              throw new StreamVerifierException( LANG.getMessage( "signature.failed", sv.getAttributes().getExtension(), fileName ) );
+          }
+        }
+      }
+
+      return baos.toByteArray();
+    }
+    catch( IOException e )
+    {
+      throw new FileUtilException( e );
+    }
+    finally
+    {
+      if( fin != null ) try { fin.close(); } catch( Exception any ) {}
+    }
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static byte[] readRawData( InputStream in )
+  throws IOException
+  {
+    byte [] bytes = new byte [ DEFAULT_BUFFER_SIZE ];
+    int n = -1;
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+    while( ( n = in.read( bytes ) ) != -1 )
+      baos.write( bytes, 0, n );
+
+    return baos.toByteArray();
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  /**
+   * Write UTF-8 representation of a String to a File. 
+   */
+  public static void writeRawData( File file, String sBytes )
+  throws IOException
+  {
+    writeRawData( file, sBytes.getBytes( DEFAULT_CHARSET ) );
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void writeRawData( InputStream in, File f )
+  throws IOException
+  {
+    OutputStream out = new FileOutputStream( f );
+    try
+    {
+      byte [] buf = new byte[ DEFAULT_BUFFER_SIZE ];
+      int n;
+
+      while( (n = in.read( buf ) ) > 0 )
+          out.write( buf, 0, n );
+      
+      out.flush();
+    }
+    finally
+    {
+      out.close();
+    }
+
+    in.close();
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static File writeTempData( byte [] bytes )
+  throws IOException
+  {
+      File f = File.createTempFile( "temp-", "-mercury-util" );
+      
+      writeRawData( f, bytes );
+      
+      return f;
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void writeRawData( File file, byte [] bytes )
+  throws IOException
+  {
+    if( file.exists() )
+      file.delete();
+
+    File parentDir = file.getParentFile();
+
+    if( !parentDir.exists() )
+      parentDir.mkdirs();
+
+    FileOutputStream fos = null;
+
+    try
+    {
+      fos = new FileOutputStream( file );
+      fos.write( bytes );
+      fos.flush();
+    }
+    catch( IOException e )
+    {
+      throw  e;
+    }
+    finally
+    {
+      if( fos != null ) try { fos.close(); } catch( Exception any ) {}
+    }
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void writeAndSign( String fName, byte [] bytes, Set<StreamVerifierFactory> vFacs )
+  throws IOException, StreamObserverException
+  {
+    ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
+    writeAndSign( fName, bais, vFacs );
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void writeAndSign( String fName, InputStream in, Set<StreamVerifierFactory> vFacs )
+  throws IOException, StreamObserverException
+  {
+    byte [] buf = new byte[ DEFAULT_BUFFER_SIZE ];
+    int n = -1;
+    HashSet<StreamVerifier> vSet = new HashSet<StreamVerifier>( vFacs.size() );
+
+    for( StreamVerifierFactory vf : vFacs )
+      vSet.add( vf.newInstance() );
+
+    FileOutputStream fout = null;
+
+    try
+    {
+      File f = new File( fName );
+
+      f.getParentFile().mkdirs();
+
+      fout = new FileOutputStream( f );
+
+      while( ( n = in.read( buf ) ) != -1 )
+      {
+        for( StreamVerifier sv : vSet )
+          sv.bytesReady( buf, 0, n );
+
+        fout.write( buf, 0, n );
+      }
+
+      fout.flush();
+      fout.close();
+      fout = null;
+
+      for( StreamVerifier sv : vSet )
+      {
+        String sig = sv.getSignature();
+        FileUtil.writeRawData( new File( fName + sv.getAttributes().getExtension() ), sig );
+      }
+
+    }
+    finally
+    {
+      if( fout != null ) try { fout.close(); } catch( Exception any ) {}
+    }
+
+  }
+
+  public List<String> dirToList( File dir, boolean includeDirs, boolean includeFiles )
+  {
+    if( ! dir.exists() )
+      return null;
+
+    File [] files = dir.listFiles();
+
+    List<String> res = new ArrayList<String>( files.length );
+
+    for( File f : files )
+      if( f.isDirectory() )
+      {
+        if( includeDirs )
+          res.add( f.getName() );
+      }
+      else
+        if( includeFiles )
+          res.add( f.getName() );
+
+    return res;
+  }
+
+  /**
+   * 
+   * @param f
+   * @param vFacs
+   * @param recurse
+   * @param force
+   * @throws IOException
+   * @throws StreamObserverException
+   */
+  public static void sign( File f, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force )
+  throws IOException, StreamObserverException
+  {
+    if( vFacs == null || vFacs.size() < 1 )
+      return;
+
+    if( f.isDirectory() )
+    {
+      if( ! recurse )
+        return;
+
+      File [] kids = f.listFiles();
+      for( File kid : kids )
+        sign( kid, vFacs, recurse, force );
+      return;
+    }
+
+    String fName = f.getAbsolutePath();
+
+    HashSet<StreamVerifier> vs = new HashSet<StreamVerifier>( vFacs.size() );
+    for( StreamVerifierFactory vf : vFacs )
+    {
+      StreamVerifier sv = vf.newInstance();
+      String ext = sv.getAttributes().getExtension();
+
+      // don't sign signature files
+      if( fName.endsWith( ext ) )
+        return;
+
+      File sf = new File( fName + ext );
+      if( sf.exists() )
+      {
+        if( force )
+          sf.delete();
+        else
+          continue;
+      }
+      vs.add( sv );
+    }
+
+    byte [] buf = new byte[ DEFAULT_BUFFER_SIZE ];
+    FileInputStream fis = null;
+    try
+    {
+      fis = new FileInputStream( f );
+      int n = -1;
+
+      while( ( n = fis.read( buf ) ) != -1 )
+      {
+        for( StreamVerifier sv : vs )
+        {
+          sv.bytesReady( buf, 0, n );
+        }
+      }
+
+      for( StreamVerifier sv : vs )
+      {
+        String sig = sv.getSignature();
+        String ext = sv.getAttributes().getExtension();
+        File sf = new File( fName + ext );
+        writeRawData( sf, sig );
+      }
+    }
+    finally
+    {
+      if( fis != null ) try { fis.close(); } catch( Exception any ) {}
+    }
+
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void verify( File f, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force )
+  throws IOException, StreamObserverException
+  {
+    if( vFacs == null || vFacs.size() < 1 )
+      return;
+
+    if( f.isDirectory() )
+    {
+      if( !recurse )
+        return;
+
+      File [] kids = f.listFiles();
+      for( File kid : kids )
+        verify( kid, vFacs, recurse, force );
+      return;
+    }
+
+    String fName = f.getAbsolutePath();
+    HashSet<StreamVerifier> vs = new HashSet<StreamVerifier>( vFacs.size() );
+    for( StreamVerifierFactory vf : vFacs )
+    {
+      StreamVerifier sv = vf.newInstance();
+      String ext = sv.getAttributes().getExtension();
+
+      // don't verify signature files
+      if( fName.endsWith( ext ) )
+        return;
+
+      File sf = new File( fName + ext );
+      if( !sf.exists() )
+      {
+        if( force )
+          throw new StreamVerifierException( LANG.getMessage( "no.mandatory.signature", f.getAbsolutePath(), sf.getAbsolutePath() ) );
+        else
+          continue;
+      }
+      else
+      {
+        String sig = readRawDataAsString( sf );
+        sv.initSignature( sig );
+      }
+      vs.add( sv );
+    }
+
+    byte [] buf = new byte[ DEFAULT_BUFFER_SIZE ];
+    FileInputStream fis = null;
+    try
+    {
+      fis = new FileInputStream( f );
+      int n = -1;
+
+      while( ( n=fis.read( buf ) ) != -1 )
+      {
+        for( StreamVerifier sv : vs )
+        {
+          sv.bytesReady( buf, 0, n );
+        }
+      }
+
+      List<String> fl = null;
+      char comma = ' ';
+
+      for( StreamVerifier sv : vs )
+      {
+        if( sv.verifySignature() )
+          continue;
+
+        if( fl == null )
+          fl = new ArrayList<String>( 4 );
+
+        fl.add( sv.getAttributes().getExtension().replace( '.', comma ) );
+        comma = ',';
+      }
+
+      if( fl != null )
+      {
+        throw new StreamVerifierException( LANG.getMessage( "file.failed.verification", f.getAbsolutePath(), fl.toString() ) );
+      }
+    }
+    finally
+    {
+      if( fis != null ) try { fis.close(); } catch( Exception any ) {}
+    }
+
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  @SuppressWarnings("static-access")
+  public static void main( String[] args )
+  throws IOException, StreamObserverException
+  {
+    Option sign      = new Option( "sign", LANG.getMessage( "option.sign" ) );
+    Option verify    = new Option( "verify", LANG.getMessage( "option.verify" ) );
+    OptionGroup  cmd = new OptionGroup();
+    cmd.addOption( sign );
+    cmd.addOption( verify );
+
+    Option recurce   = new Option( "r", LANG.getMessage( "option.r" ) );
+    Option force     = new Option( "force", LANG.getMessage( "option.force" ) );
+
+    OptionGroup  sig = new OptionGroup();
+    Option sha1      = new Option( "sha1", LANG.getMessage( "option.sha1" ) );
+    Option pgp       = new Option( "pgp", LANG.getMessage( "option.pgp" ) );
+    sig.addOption( sha1 );
+    sig.addOption( pgp );
+
+    Option keyring   = OptionBuilder.withArgName( "file" )
+                                    .hasArg()
+                                    .withType( java.io.File.class )
+                                    .withDescription( LANG.getMessage( "option.keyring" ) )
+                                    .create( "keyring" )
+                                    ;
+    Option keyid     = OptionBuilder.withArgName( "hexstring" )
+                                    .hasArg()
+                                    .withDescription( LANG.getMessage( "option.keyid" ) )
+                                    .create( "keyid" )
+                                    ;
+    Option keypass   = OptionBuilder.withArgName( "string" )
+                                    .hasArg()
+                                    .withDescription( LANG.getMessage( "option.keypass" ) )
+                                    .create( "keypass" )
+                                    ;
+
+    Options options = new Options();
+    options.addOptionGroup( cmd );
+    options.addOptionGroup( sig );
+
+    options.addOption( recurce );
+    options.addOption( force );
+
+    options.addOption( keyring );
+    options.addOption( keyid );
+    options.addOption( keypass );
+
+    CommandLine commandLine = null;
+    CommandLineParser parser = new GnuParser();
+
+    if( args == null || args.length < 2 )
+    {
+      HelpFormatter formatter = new HelpFormatter();
+      formatter.printHelp( "mercury-util", options );
+      return;
+    }
+
+    try
+    {
+        commandLine = parser.parse( options, args );
+    }
+    catch( ParseException e )
+    {
+        System.err.println( "Command line parsing eror: " + e.getMessage() );
+        return;
+    }
+
+    Set<StreamVerifierFactory> vFacs = new HashSet<StreamVerifierFactory>( 4 );
+
+    if( commandLine.hasOption( "pgp" ) )
+    {
+      if( commandLine.hasOption( "sign" ) && commandLine.hasOption( "keyring" ) && commandLine.hasOption( "keyid" ) )
+      {
+        BufferedReader r = new BufferedReader( new InputStreamReader( System.in ) );
+        String pass = commandLine.hasOption( "keypass" ) ? commandLine.getOptionValue( "keypass" ) : r.readLine();
+
+        vFacs.add( 
+            new PgpStreamVerifierFactory(
+                    new StreamVerifierAttributes( PgpStreamVerifierFactory.DEFAULT_EXTENSION, false, true )
+                    , new FileInputStream( commandLine.getOptionValue( "keyring" ) )
+                    , commandLine.getOptionValue( "keyid" )
+                    , pass
+                                        )
+                    );
+      }
+      else if( commandLine.hasOption( "verify" ) && commandLine.hasOption( "keyring" ) )
+      {
+
+        vFacs.add(
+            new PgpStreamVerifierFactory(
+                    new StreamVerifierAttributes( PgpStreamVerifierFactory.DEFAULT_EXTENSION, false, true )
+                    , new FileInputStream( commandLine.getOptionValue( "keyring" ) )
+                                        )
+                    );
+      }
+      else
+      {
+        System.err.println( LANG.getMessage( "bad.pgp.args" ) );
+        return;
+      }
+    }
+
+    if( commandLine.hasOption("sha1") )
+    {
+      vFacs.add( new SHA1VerifierFactory( true,false ) );
+    }
+
+    try
+    {
+      signAll( commandLine.getArgList(), vFacs, commandLine.hasOption( "r" ), commandLine.hasOption( "force" ), commandLine.hasOption( "sign" ) );
+    }
+    catch( Exception e )
+    {
+      System.err.println( "Bummer: " + e.getMessage() );
+      return;
+    }
+    System.out.println( "Done" );
+
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  private static void signAll( List<String> fileNames, Set<StreamVerifierFactory> vFacs, boolean recurse, boolean force, boolean sign )
+  throws IOException, StreamObserverException
+  {
+    if( vFacs == null || vFacs.size() < 1 )
+    {
+      System.err.println( "no.verifiers" );
+      return;
+    }
+
+    File f = null;
+
+    for( String fName : fileNames )
+    {
+      f = new File( fName );
+      if( ! f.exists() )
+      {
+        System.out.println( LANG.getMessage( "file.not.exists", fName ) );
+        continue;
+      }
+      if( f.isDirectory() && ! recurse )
+      {
+        System.out.println( LANG.getMessage( "file.is.directory", fName ) );
+        continue;
+      }
+      if( sign )
+        sign( f, vFacs, recurse, force );
+      else
+        verify( f, vFacs, recurse, force );
+    }
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  /**
+   * try to acquire lock on specified directory for <code>millis<code> milliseconds
+   * 
+   * @param dir directory to lock
+   * @param millis how long to wait for the lock before surrendering
+   * @param sleepFor how long to sleep between attempts
+   * 
+   * @return obtained FileLock or null
+   * @throws IOException if there were problems obtaining the lock
+   */
+  public static FileLockBundle lockDir( String dir, long millis, long sleepFor )
+  throws IOException
+  {
+
+    File df = new File( dir );
+
+    boolean exists = df.exists();
+
+    for( int i=0; i<10 && !exists; i++ )
+    {
+      try{ Thread.sleep( 1l ); } catch( InterruptedException e ){}
+      df.mkdirs();
+      exists = df.exists();
+      LOG.info( LANG.getMessage( "had.to.create.directory", dir, exists + "" ) );
+    }
+
+    if( !exists )
+      throw new IOException( LANG.getMessage( "cannot.create.directory", dir ) );
+
+    if( !df.isDirectory() )
+      throw new IOException( LANG.getMessage( "file.is.not.directory", dir, df.exists() + "", df.isDirectory() + "", df.isFile() + "" ) );
+
+    File lockFile = new File( dir,LOCK_FILE );
+
+    long start = System.currentTimeMillis();
+
+    for( long now = start; ( now - start ) < millis; now = System.currentTimeMillis() )
+      try
+      {
+        synchronized( FileUtil.class )
+        {
+          if( !lockFile.exists() )
+          {
+            writeRawData( lockFile, "lock" );
+            lockFile.deleteOnExit();
+            return new FileLockBundle( dir );
+          }
+        }
+        Thread.sleep( sleepFor );
+
+      }
+      catch( InterruptedException ie )
+      {
+      }
+
+      // too long a wait
+      return null;
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  /**
+   * try to acquire lock on specified directory for <code>millis<code> milliseconds
+   * 
+   * @param dir directory to lock
+   * @param millis how long to wait for the lock before surrendering
+   * @param sleepFor how long to sleep between attempts
+   * 
+   * @return obtained FileLock or null
+   * @throws IOException if there were problems obtaining the lock
+   */
+  public static FileLockBundle lockDirNio( String dir, long millis, long sleepFor )
+  throws IOException
+  {
+    File df = new File( dir );
+
+    boolean exists = df.exists(); 
+
+    for( int i = 0; i < 10 && !exists; i++ )
+    {
+      try{ Thread.sleep( 1l ); } catch( InterruptedException e ){}
+      df.mkdirs();
+      exists = df.exists();
+      LOG.info( LANG.getMessage( "had.to.create.directory", dir, exists + "" ) );
+    }
+
+    if( !exists )
+      throw new IOException( LANG.getMessage( "cannot.create.directory", dir ) );
+
+    if( !df.isDirectory() )
+      throw new IOException( LANG.getMessage( "file.is.not.directory", dir, df.exists() + "", df.isDirectory() + "", df.isFile() + "" ) );
+
+    File lockFile = new File( dir,LOCK_FILE );
+    if( !lockFile.exists() )
+      writeRawData( lockFile, "lock" );
+    lockFile.deleteOnExit();
+
+    FileChannel ch = new RandomAccessFile( lockFile, "rw" ).getChannel();
+    FileLock lock = null;
+
+    long start = System.currentTimeMillis();
+
+    for(;;)
+      try
+      {
+        lock = ch.tryLock( 0L, 4L, false );
+
+        if( lock == null )
+          throw FILE_LOCKED;
+
+        return new FileLockBundle( dir, ch, lock );
+      }
+      catch( OverlappingFileLockException oe )
+      {
+        try { Thread.sleep( sleepFor ); } catch( InterruptedException e ){}
+        if( System.currentTimeMillis() - start > millis )
+          return null;
+      }
+
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static synchronized void unlockDir( String dir )
+  {
+    try
+    {
+      File df = new File( dir );
+      if( !df.isDirectory() )
+        throw new IOException( LANG.getMessage( "file.is.not.directory", dir ) );
+
+      File lock = new File( dir,LOCK_FILE );
+      if( lock.exists() )
+        lock.delete();
+    }
+    catch( IOException e )
+    {
+      LOG.error( e.getMessage() );
+    }
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static final Set<StreamVerifierFactory> vSet( StreamVerifierFactory... facs )
+  {
+    if( facs == null || facs.length < 1 )
+      return null;
+
+    HashSet<StreamVerifierFactory> res = new HashSet<StreamVerifierFactory>( facs.length );
+    for( StreamVerifierFactory f : facs )
+    {
+      res.add( f );
+    }
+
+    return res;
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static final Set<StreamObserverFactory> oSet( StreamObserverFactory... facs )
+  {
+    if( facs == null || facs.length < 1 )
+      return null;
+
+    HashSet<StreamObserverFactory> res = new HashSet<StreamObserverFactory>( facs.length );
+    for( StreamObserverFactory f : facs )
+    {
+      res.add( f );
+    }
+
+    return res;
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static void renameFile( File dir, String from, String to )
+  {
+    if( dir == null )
+      return;
+
+    File [] files = dir.listFiles();
+
+    if( files == null || files.length < 1 )
+      return;
+
+    for( File f : files )
+    {
+      if( f.isDirectory() )
+        renameFile( f, from, to );
+      else if( from.equals( f.getName() ) )
+      {
+        f.renameTo( new File( f.getParent(), to ) );
+      }
+    }
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static int depth( File file )
+  {
+    if( file == null || !file.exists() )
+      throw new IllegalArgumentException( LANG.getMessage( "file.not.exists.error", file == null ? "null" : file.getAbsolutePath() ) );
+
+    if( file.isFile() )
+      return 0;
+
+    File [] files = file.listFiles();
+
+    int max = 0;
+
+    for( File f : files )
+    {
+      if( f.isDirectory() )
+      {
+        int res = depth( f );
+        if( res > max )
+          max = res;
+      }
+    }
+
+    return max + 1;
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static InputStream toStream( String resource )
+  throws MalformedURLException, IOException
+  {
+    if( resource == null )
+      return null;
+    
+    int ind = resource.indexOf( PROTOCOL_DELIM );
+    
+    if( ind > 1 )
+    {
+        String protocol = resource.substring( 0, ind );
+        resource = resource.substring( ind + PROTOCOL_DELIM_LEN );
+
+        for( int i=0; i<URL_PROTOCOLS.length; i++ )
+        {
+            String p = URL_PROTOCOLS[i];
+            
+            if( protocol.regionMatches( true, 0, p, 0, p.length() ) )
+              return new URL( p+PROTOCOL_DELIM+resource).openStream();
+        }
+    }
+
+    return new FileInputStream( new File(resource) );
+  }
+  //---------------------------------------------------------------------------------------------------------------
+  public static boolean isLocalResource( String resource )
+  {
+    if( resource == null )
+      return true;
+    
+    int ind = resource.indexOf( PROTOCOL_DELIM );
+    
+    if( ind > 1 )
+    {
+        String protocol = resource.substring( 0, ind );
+
+        for( int i=0; i<LOCAL_PROTOCOLS.length; i++ )
+        {
+            String p = LOCAL_PROTOCOLS[i];
+            
+            if( protocol.regionMatches( true, 0, p, 0, p.length() ) )
+              return true;
+        }
+    }
+    else
+        return true;
+
+    return false;
+  }
+  // -----------------------------------------------------
+    public static final void unZip( InputStream zipInputStream, File destDir )
+        throws FileNotFoundException, IOException
+    {
+        ZipInputStream zis = new ZipInputStream( zipInputStream );
+
+        BufferedOutputStream dest = null;
+        ZipEntry entry;
+
+        while ( ( entry = zis.getNextEntry() ) != null )
+        {
+            String entryName = entry.getName();
+            
+            File fo = new File( destDir, entryName );
+            
+            if( LOG.isDebugEnabled() )
+                LOG.debug( "Extracting: " + fo.getCanonicalPath() );
+
+            int count;
+            byte data[] = new byte[ DEFAULT_BUFFER_SIZE ];
+
+            // write the files to the disk
+            if ( entry.isDirectory() )
+            {
+                fo.mkdirs();
+                continue;
+            }
+            
+            fo.getParentFile().mkdirs();
+
+            FileOutputStream fos = new FileOutputStream( fo );
+            
+            dest = new BufferedOutputStream( fos, DEFAULT_BUFFER_SIZE );
+            
+            while ( ( count = zis.read( data, 0, DEFAULT_BUFFER_SIZE ) ) != -1 )
+            {
+                dest.write( data, 0, count );
+            }
+            
+            dest.flush();
+            
+            dest.close();
+        }
+        
+        zis.close();
+
+        if( LOG.isDebugEnabled() )
+            LOG.debug( destDir + " - done." );
+    }
+  //---------------------------------------------------------------------------------------------------------------
+  //---------------------------------------------------------------------------------------------------------------
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtil.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtilException.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtilException.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtilException.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtilException.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,72 @@
+/**
+ *  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.util;
+
+/**
+ *
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class FileUtilException
+    extends Exception
+{
+
+  /**
+   * 
+   */
+  public FileUtilException()
+  {
+    // TODO Auto-generated constructor stub
+  }
+
+  /**
+   * @param message
+   */
+  public FileUtilException(
+      String message )
+  {
+    super( message );
+    // TODO Auto-generated constructor stub
+  }
+
+  /**
+   * @param cause
+   */
+  public FileUtilException(
+      Throwable cause )
+  {
+    super( cause );
+    // TODO Auto-generated constructor stub
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public FileUtilException(
+      String message,
+      Throwable cause )
+  {
+    super( message, cause );
+    // TODO Auto-generated constructor stub
+  }
+
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtilException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/FileUtilException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Messages.properties
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Messages.properties?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Messages.properties (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Messages.properties Wed Apr 22 22:56:48 2009
@@ -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.
+#
+signature.failed=Signature "{0}": verification failed for file {1}
+no.signature.file=Verifier for {0} is mandatory, but file {1} does not exist
+cannot.read.signature.file=Cannot read signature file {0}, error: {1}
+option.sha1=produce SHA1 signatures 
+option.sign=create signatures for specified algorithms. Use -force to overwrite existing ones
+option.verify=verify signatures for specified algorithms. Use -force to fail on non-existing signatures
+option.pgp=produce PGP signatures, requires -keyring and -keyid options 
+option.keyring=full path of the secret keyring file
+option.keyid=id of the key in the secret keyring file to be used in the signature
+option.keypass=key password
+option.r=recursevly sign all unsigned files
+option.force=overwrite existing signatures
+bad.pgp.args=pgp option requires both -keyring and -keyid to be specified
+no.verifiers=No signature generators requested - exiting
+file.not.exists=File "{0}" does not exist. Skipping ..
+file.is.directory=File "{0}" is a folder and no recursive option is specified. Skipping ..
+no.mandatory.signature=Mandatory signature {1} does not exist for file {0}
+file.failed.verification=File {0} failed following verifications: {1}
+cannot.create.directory=Cannot create directory {0}
+file.is.not.directory=Specified file {0} is not a directory: exists={1}, isDir={2}, isFile={3}
+reading.empty.file=File to read {0} has zero length
+had.to.create.directory=Directory {0} did not exist. Created: {1}
+null.file=Null supplied instead on File instance
+file.not.exists.error=File {0} does not exist.

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Messages.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Messages.properties
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Monitor.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Monitor.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Monitor.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Monitor.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,29 @@
+/**
+ *  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.util;
+
+/**
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public interface Monitor
+{
+    public abstract void message( String msg );
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Monitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Monitor.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/TimeUtil.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/TimeUtil.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/TimeUtil.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/TimeUtil.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,154 @@
+/**
+ *  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.util;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.TimeZone;
+
+/**
+ * @author Oleg Gusakov
+ * @version $Id$
+ */
+public class TimeUtil
+{
+    public static final java.util.TimeZone TS_TZ = java.util.TimeZone.getTimeZone( "UTC" );
+
+    public static final java.text.DateFormat TS_FORMAT = new java.text.SimpleDateFormat( "yyyyMMddHHmmss" );
+
+    public static final java.text.DateFormat SN_TS_FORMAT = new java.text.SimpleDateFormat( "yyyyMMdd.HHmmss" );
+
+    static
+    {
+        TS_FORMAT.setTimeZone( TS_TZ );
+    }
+
+    /**
+     * @return current UTC timestamp by yyyyMMddHHmmss mask
+     */
+    public static String getUTCTimestamp()
+    {
+        return getUTCTimestamp( new Date() );
+    }
+
+    /**
+     * @return current UTC timestamp by yyyyMMddHHmmss mask as a long int
+     */
+    public static long getUTCTimestampAsLong()
+    {
+        return Long.parseLong( getUTCTimestamp( new Date() ) );
+    }
+
+    /**
+     * @return current UTC timestamp by yyyyMMddHHmmss mask as a long int
+     */
+    public static long getUTCTimestampAsMillis()
+    {
+        return Long.parseLong( getUTCTimestamp( new Date() ) );
+    }
+
+    /**
+     * @param date
+     * @return current date converted to UTC timestamp by yyyyMMddHHmmss mask
+     */
+    public static String getUTCTimestamp( Date date )
+    {
+        return TS_FORMAT.format( date );
+    }
+
+    /**
+     * convert timestamp to millis
+     * 
+     * @param ts timestamp to convert. Presumed to be a long of form yyyyMMddHHmmss
+     * @return millis, corresponding to the supplied TS
+     * @throws ParseException is long does not follow the format
+     */
+    public static long toMillis( long ts )
+        throws ParseException
+    {
+        return toMillis( "" + ts );
+    }
+
+    /**
+     * convert timestamp to millis
+     * 
+     * @param ts timestamp to convert. Presumed to be a string of form yyyyMMddHHmmss
+     * @return millis, corresponding to the supplied TS
+     * @throws ParseException is long does not follow the format
+     */
+    public static long toMillis( String ts )
+        throws ParseException
+    {
+        Date dts = TS_FORMAT.parse( ts );
+
+        return dts.getTime();
+    }
+    
+    /**
+     * conver SNAPSHOT timestampt into millis
+     * 
+     * @param ts
+     * @return
+     * @throws ParseException
+     */
+    public static long snTstoMillis( String ts )
+    throws ParseException
+    {
+        if( ts == null )
+            return 0;
+        
+        int dot = ts.indexOf( '.' );
+        
+        int dash = ts.indexOf( '-' );
+        
+        int lastInd = dash == -1 ? ts.length() : dash;
+        
+        if( dot == -1 )
+            return toMillis( ts );
+        
+        return toMillis( ts.substring( 0, dot )+ts.substring( dot+1, lastInd ) );
+    }
+    
+    /**
+     * convert current millis to UTC timestamp
+     * @param local
+     * @return
+     */
+    public static String defaultToSnTs( long local )
+    {
+      Date lDate = new Date(local);
+
+      SN_TS_FORMAT.setTimeZone( TS_TZ );
+      return SN_TS_FORMAT.format(lDate);
+    }
+
+    public static void main( String[] args ) throws Exception
+    {
+        if( args == null || args.length < 0 )
+            return;
+        
+        if( "-t".equals( args[0] ) )
+        {
+            System.out.println( args[1]+" => " + new Date( toMillis( args[1] ) ) ) ;
+            return;
+        }
+    }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/TimeUtil.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/TimeUtil.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Util.java
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Util.java?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Util.java (added)
+++ maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Util.java Wed Apr 22 22:56:48 2009
@@ -0,0 +1,106 @@
+/**
+ *  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.util;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Configurable;
+
+/**
+ * general utility helpers
+ *
+ * @author Oleg Gusakov
+ * @version $Id$
+ *
+ */
+public class Util
+{
+    public static final boolean bWindows = File.pathSeparatorChar == ';';
+    
+    public static final boolean isWindows()
+    {
+      return bWindows;
+    }
+    
+   @SuppressWarnings("unchecked")
+  public static final boolean isEmpty( Collection o )
+   {
+     return o == null || o.isEmpty();
+   }
+   
+   public static final boolean isEmpty( String o )
+   {
+     return o == null || o.length() < 1;
+   }
+   
+   public static final boolean isEmpty( File o )
+   {
+     return o == null || !o.exists() || o.length() < 1L;
+   }
+
+   public static final boolean isEmpty( Object [] o )
+   {
+     return o == null || o.length < 1;
+   }
+
+   public static final boolean isEmpty( Map o )
+   {
+     return o == null || o.isEmpty();
+   }
+
+   public static final boolean isEmpty( Object o )
+   {
+     return o == null;
+   }
+
+   public static final String nvlS( String s, String dflt )
+   {
+     return isEmpty(s) ? dflt : s;
+   }
+   
+   public static final void say( String msg, Monitor monitor )
+   {
+       if( monitor != null )
+           monitor.message( msg );
+   }
+   
+   public static final String convertLength( long sz )
+   {
+       if( sz < 5000L )
+           return sz+" bytes";
+       
+       return (int)(Math.round( sz / 1024.))+" kb";
+   }
+   
+   public static Map<String,Object> mapOf( Object [][] entries )
+   {
+       if( entries == null )
+           return null;
+       
+       Map<String,Object> map = new HashMap<String, Object>( entries.length );
+       
+       for( Object [] kv : entries )
+           map.put( (String)kv[0], kv[1] );
+       
+       return map;
+   }
+}

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Util.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/java/org/apache/maven/mercury/util/Util.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/mdo/cached-metadata.mdo
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/mdo/cached-metadata.mdo?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/mdo/cached-metadata.mdo (added)
+++ maven/mercury/trunk/mercury-core/src/main/mdo/cached-metadata.mdo Wed Apr 22 22:56:48 2009
@@ -0,0 +1,117 @@
+<!--
+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.
+-->
+
+<model>
+  <id>cached-metadata</id>
+  
+  <name>CachedMetadata</name>
+  <description>Per-directory repository metadata.</description>
+  
+  <defaults>
+    <default>
+      <key>package</key>
+      <value>org.apache.maven.mercury.repository.cache.md</value>
+    </default>
+  </defaults>
+  
+  <classes>
+
+    <class rootElement="true">
+      <name>CachedRawMetadata</name>
+      <version>1.0.0</version>
+      <fields>
+        
+        <field>
+          <name>lastUpdated</name>
+          <version>1.0.0</version>
+          <type>String</type>
+          <description>When the metadata was last updated</description>
+        </field>
+        
+        <field>
+          <name>elements</name>
+          <version>1.0.0</version>
+          <description>group of metadata elements</description>
+          <association>
+            <type>Element</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+      </fields>
+     </class>
+
+    <class>
+      <name>Element</name>
+      <version>1.0.0</version>
+      <description>metadata element</description>
+      <fields>
+        <field>
+          <name>name</name>
+          <version>1.0.0</version>
+          <description>name of this element</description>
+          <type>String</type>
+        </field>
+        
+        <field>
+          <name>attributes</name>
+          <version>1.0.0</version>
+          <description>group of metadata element attributes</description>
+          <association>
+            <type>Attribute</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+
+        <field>
+          <name>elements</name>
+          <version>1.0.0</version>
+          <description>group of metadata element elements</description>
+          <association>
+            <type>Element</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+
+      </fields>
+    </class>
+
+    <class>
+      <name>Attribute</name>
+      <version>1.0.0</version>
+      <description>generic attribute - name/value pair</description>
+      <fields>
+        <field>
+          <name>name</name>
+          <type>String</type>
+          <required>true</required>
+          <version>1.0.0</version>
+          <description>name of this attribute</description>
+        </field>
+        <field>
+          <name>value</name>
+          <type>String</type>
+          <required>true</required>
+          <version>1.0.0</version>
+          <description>value of this attribute</description>
+        </field>
+      </fields>
+    </class>
+    
+  </classes>
+</model>

Propchange: maven/mercury/trunk/mercury-core/src/main/mdo/cached-metadata.mdo
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/mdo/cached-metadata.mdo
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: maven/mercury/trunk/mercury-core/src/main/mdo/forest.mdo
URL: http://svn.apache.org/viewvc/maven/mercury/trunk/mercury-core/src/main/mdo/forest.mdo?rev=767705&view=auto
==============================================================================
--- maven/mercury/trunk/mercury-core/src/main/mdo/forest.mdo (added)
+++ maven/mercury/trunk/mercury-core/src/main/mdo/forest.mdo Wed Apr 22 22:56:48 2009
@@ -0,0 +1,153 @@
+<!--
+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.
+-->
+
+<model>
+  <id>forest</id>
+  
+  <name>Forrest</name>
+  
+  <defaults>
+    <default>
+      <key>package</key>
+      <value>org.apache.maven.mercury.metadata.forest</value>
+    </default>
+  </defaults>
+  
+  <classes>
+
+    <class rootElement="true">
+      <name>Forest</name>
+      <version>1.0.0</version>
+      <fields>
+
+        <field>
+          <name>trees</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Tree</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+
+      </fields>
+   </class>
+
+    <class>
+      <name>Tree</name>
+      <version>1.0.0</version>
+      <fields>
+
+        <field>
+          <name>timestamp</name>
+          <version>1.0.0</version>
+          <type>String</type>
+        </field>
+
+        <field>
+          <name>scope</name>
+          <version>1.0.0</version>
+          <type>String</type>
+        </field>
+        
+        <field>
+          <name>request</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Node</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        
+        <field>
+          <name>inclusions</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Node</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        
+        <field>
+          <name>exclusions</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Node</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+        
+        <field>
+          <name>dirtyTree</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Node</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+         
+        <field>
+          <name>result</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Node</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+
+      </fields>
+   </class>
+
+    <class>
+      <name>Node</name>
+      <version>1.0.0</version>
+
+      <fields>
+
+        <field>
+          <name>name</name>
+          <version>1.0.0</version>
+          <type>String</type>
+        </field>
+
+        <field>
+          <name>scope</name>
+          <version>1.0.0</version>
+          <type>String</type>
+        </field>
+
+        <field>
+          <name>level</name>
+          <version>1.0.0</version>
+          <type>long</type>
+        </field>
+         
+        <field>
+          <name>children</name>
+          <version>1.0.0</version>
+          <association>
+            <type>Node</type>
+            <multiplicity>*</multiplicity>
+          </association>
+        </field>
+
+      </fields>
+    </class>
+
+  </classes>
+</model>

Propchange: maven/mercury/trunk/mercury-core/src/main/mdo/forest.mdo
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: maven/mercury/trunk/mercury-core/src/main/mdo/forest.mdo
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision