ACE-499 - support authentication in AceObrRepository 

- applied patch from @brampouwelse;
- this closes #3.



git-svn-id: https://svn.apache.org/repos/asf/ace/trunk@1729606 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/.gitignore b/.gitignore
index c4c5e06..0908987 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,7 @@
 */reports/
 *~
 */.settings/
+*/bundle-cache
+*/store
+*/test-output
+rat-report.xml
diff --git a/org.apache.ace.bnd/bnd.bnd b/org.apache.ace.bnd/bnd.bnd
index b75489f..f502901 100644
--- a/org.apache.ace.bnd/bnd.bnd
+++ b/org.apache.ace.bnd/bnd.bnd
@@ -2,5 +2,8 @@
 
 -sub: *.bnd
 -buildpath: \
+	osgi.cmpn,\
 	biz.aQute.bnd,\
-	biz.aQute.repository
+	biz.aQute.repository,\
+	org.apache.ace.connectionfactory;version=latest
+
diff --git a/org.apache.ace.bnd/repository.bnd b/org.apache.ace.bnd/repository.bnd
index 13340ac..0bd7117 100644
--- a/org.apache.ace.bnd/repository.bnd
+++ b/org.apache.ace.bnd/repository.bnd
@@ -1,6 +1,15 @@
 # Licensed to the Apache Software Foundation (ASF) under the terms of ASLv2 (http://www.apache.org/licenses/LICENSE-2.0).
 
-Bundle-Version: 1.0.1
+Bundle-Version: 1.1.0
 Bundle-Name: Apache ACE OBR Repository
 Bundle-Description: Provides an ACE Bnd Repository implementation
-Export-Package: org.apache.ace.bnd.repository
\ No newline at end of file
+Export-Package: \
+	org.apache.ace.bnd.repository,\
+	org.apache.commons.codec,\
+	org.apache.commons.codec.binary,\
+	org.osgi.service.cm,\
+	org.osgi.service.useradmin,\
+	org.apache.ace.connectionfactory,\
+	org.apache.ace.connectionfactory.impl
+
+-includeresource: META-INF/services=services
\ No newline at end of file
diff --git a/org.apache.ace.bnd/services/org.apache.ace.connectionfactory.ConnectionFactory b/org.apache.ace.bnd/services/org.apache.ace.connectionfactory.ConnectionFactory
new file mode 100644
index 0000000..dd148dc
--- /dev/null
+++ b/org.apache.ace.bnd/services/org.apache.ace.connectionfactory.ConnectionFactory
@@ -0,0 +1 @@
+org.apache.ace.connectionfactory.impl.ConnectionFactoryImpl
\ No newline at end of file
diff --git a/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceObrRepository.java b/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceObrRepository.java
index db90cb7..a6e475b 100644
--- a/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceObrRepository.java
+++ b/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceObrRepository.java
@@ -28,6 +28,8 @@
 import java.net.URLConnection;
 import java.util.Map;
 
+import org.apache.ace.connectionfactory.ConnectionFactory;
+
 import aQute.bnd.deployer.repository.FixedIndexedRepo;
 
 /**
@@ -88,7 +90,19 @@
         try {
 
             URL url = new URL(m_endpoint, "?filename=" + filename);
-            URLConnection connection = url.openConnection();
+            
+            URLConnection connection = null;
+            if (registry != null) {
+                ConnectionFactory connectionFactory = registry.getPlugin(ConnectionFactory.class);
+                if (connectionFactory != null) {
+                    connection = connectionFactory.createConnection(url);
+                }
+            }
+            
+            if (connection == null) {
+                connection = url.openConnection();
+            }
+            
             connection.setDoOutput(true);
             connection.setDoInput(true);
             connection.setUseCaches(false);
diff --git a/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceUrlConnector.java b/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceUrlConnector.java
new file mode 100644
index 0000000..ce03a59
--- /dev/null
+++ b/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/AceUrlConnector.java
@@ -0,0 +1,168 @@
+/*
+ * 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.ace.bnd.repository;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ServiceLoader;
+import java.util.StringTokenizer;
+
+import org.apache.ace.connectionfactory.ConnectionFactory;
+import org.osgi.service.cm.ConfigurationException;
+import org.osgi.service.cm.ManagedServiceFactory;
+import org.osgi.service.useradmin.User;
+
+import aQute.bnd.service.Plugin;
+import aQute.bnd.service.url.TaggedData;
+import aQute.bnd.service.url.URLConnector;
+import aQute.service.reporter.Reporter;
+
+/**
+ * BND URLConnector plugin based on the Ace ConnectionFactory
+ * 
+ * Can be configured as a bnd plugin with a configs configuration property that contains 
+ * comma separated list of connection factory configurations
+ * 
+ * Example: 
+ *  -plugin: org.apache.ace.bnd.repository.AceUrlConnector; \
+ *      configs=${workspace}/run-server-allinone/conf/org.apache.ace.connectionfactory/obr.cfg;
+ * 
+ * Note: The default ace configurations contain placeholders in the baseURL property this doesn't 
+ * work when the configuration is used in this plugin as these placeholders are not replaced by bnd.
+ */
+public class AceUrlConnector implements URLConnector, Plugin, ConnectionFactory {
+    
+    private static final String HEADER_IF_NONE_MATCH    = "If-None-Match";
+    private static final String HEADER_ETAG             = "ETag";
+    private static final int    RESPONSE_NOT_MODIFIED   = 304;
+    
+    private ConnectionFactory m_connectionFactory;
+    
+    public AceUrlConnector() {
+        m_connectionFactory = getConnectionFactory();
+    }
+    
+    public AceUrlConnector(ConnectionFactory connectionFactory) {
+        m_connectionFactory = connectionFactory;
+    }
+
+    private ConnectionFactory getConnectionFactory() {
+        ServiceLoader<ConnectionFactory> loader = ServiceLoader.load(ConnectionFactory.class, getClass().getClassLoader());
+        return loader.iterator().next();
+    }
+    
+    @Override
+    public TaggedData connectTagged(URL url, String tag) throws IOException {
+        TaggedData result;
+        URLConnection connection = m_connectionFactory.createConnection(url);
+        if (connection instanceof HttpURLConnection) {
+            HttpURLConnection httpConnection = (HttpURLConnection) connection;
+            
+            httpConnection.setUseCaches(true);
+            if (tag != null) {
+                httpConnection.setRequestProperty(HEADER_IF_NONE_MATCH, tag);
+            }
+            int responseCode = httpConnection.getResponseCode();
+            if (responseCode == RESPONSE_NOT_MODIFIED) {
+                result = null;
+                httpConnection.disconnect();
+            } else {
+                String responseTag = httpConnection.getHeaderField(HEADER_ETAG);
+                result = new TaggedData(responseTag, connection.getInputStream());
+            }
+        } else {
+            // Non-HTTP so ignore all this tagging malarky
+            result = new TaggedData(null, connection.getInputStream());
+        }
+        
+        return result;
+    }
+
+    @Override
+    public TaggedData connectTagged(URL url) throws IOException {
+        return connectTagged(url, null);
+    }
+
+    @Override
+    public InputStream connect(URL url) throws IOException {
+        return m_connectionFactory.createConnection(url).getInputStream();
+    }
+    
+    @Override
+    public URLConnection createConnection(URL url) throws IOException {
+        return m_connectionFactory.createConnection(url);
+    }
+    
+    @Override
+    public URLConnection createConnection(URL url, User user) throws IOException {
+        return m_connectionFactory.createConnection(url, user);
+    }
+
+    @Override
+    public void setProperties(Map<String, String> map) {
+        String configFileList = map.get("configs");
+        if (configFileList == null) {
+            throw new IllegalArgumentException("'configs' must be specified on HttpBasicAuthURLConnector");
+        }
+        
+        ConnectionFactory connectionFactory = getConnectionFactory();
+        ManagedServiceFactory managedServiceFactory = (ManagedServiceFactory) connectionFactory;
+        
+        StringTokenizer tokenizer = new StringTokenizer(configFileList, ",");
+        while (tokenizer.hasMoreTokens()) {
+            String configFileName = tokenizer.nextToken().trim();
+
+            File file = new File(configFileName);
+            if (file.exists()) {
+                
+                try {
+                    Properties properties = new Properties();
+                    properties.load(new FileInputStream(file));
+                    
+                    Dictionary<String, String> dict = new Hashtable<>();
+                    for (Object key : properties.keySet()) {
+                        String value = (String) properties.get(key);
+                        dict.put((String) key, value);
+                    }
+                    
+                    managedServiceFactory.updated(file.getAbsolutePath(), dict);
+                } catch (IOException | ConfigurationException e) {
+                    
+                }
+            }
+            
+            m_connectionFactory = connectionFactory;
+        }
+    }
+
+    @Override
+    public void setReporter(Reporter reporter) {
+        
+    }
+
+}
diff --git a/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/packageinfo b/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/packageinfo
index a4f1546..b1793a2 100644
--- a/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/packageinfo
+++ b/org.apache.ace.bnd/src/org/apache/ace/bnd/repository/packageinfo
@@ -1 +1 @@
-version 1.0
\ No newline at end of file
+version 1.1.0
\ No newline at end of file
diff --git a/org.apache.ace.gogo/bnd.bnd b/org.apache.ace.gogo/bnd.bnd
index 97f142b..e14f6cc 100644
--- a/org.apache.ace.gogo/bnd.bnd
+++ b/org.apache.ace.gogo/bnd.bnd
@@ -14,9 +14,10 @@
 
 Bundle-Name: Apache ACE Gogo commands
 Bundle-Description: Provides Gogo commands for working with ACE	
-Bundle-Version: 1.0.1
+Bundle-Version: 1.0.2
 Bundle-Activator: org.apache.ace.gogo.Activator
-Private-Package: org.apache.ace.bnd.repository,\
+Private-Package: \
+	org.apache.ace.bnd.repository,\
 	org.apache.ace.gogo,\
 	org.apache.ace.gogo.execute,\
 	org.apache.ace.gogo.math,\