blob: a6e475b0af1bddcb36eaaf9cd543fcbd1305e62e [file] [log] [blame]
/*
* 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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.util.Map;
import org.apache.ace.connectionfactory.ConnectionFactory;
import aQute.bnd.deployer.repository.FixedIndexedRepo;
/**
* BND repository implementation that supports write capabilities to an Apache ACE OBR.
*
*/
public class AceObrRepository extends FixedIndexedRepo {
private URL m_endpoint;
private boolean m_verbose;
@Override
public synchronized void setProperties(Map<String, String> map) {
super.setProperties(map);
String location = getLocation();
try {
m_endpoint = new URL(location.substring(0, location.lastIndexOf("/") + 1));
}
catch (MalformedURLException e) {
throw new IllegalArgumentException("Failed to determin location endpoint", e);
}
m_verbose = map.get("verbose") == null ? false : Boolean.parseBoolean(map.get("verbose"));
}
@Override
public boolean canWrite() {
return true;
}
@Override
public synchronized PutResult put(InputStream stream, PutOptions options) throws Exception {
if (options == null)
options = DEFAULTOPTIONS;
if (options.type == null)
options.type = PutOptions.BUNDLE;
if (stream == null)
throw new IllegalArgumentException("No stream and/or options specified");
PutResult result = new PutResult();
result.artifact = upload(stream, "", options.type);
reset();
return result;
}
public URL getEndpoint() {
return m_endpoint;
}
public URI upload(InputStream stream, String filename, String mimetype) throws Exception {
OutputStream output = null;
String location = null;
try {
URL url = new URL(m_endpoint, "?filename=" + filename);
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);
if (mimetype != null) {
connection.setRequestProperty("Content-Type", mimetype);
}
else {
// We need a mimetype or Jetty will throw a 500 Form too large
connection.setRequestProperty("Content-Type", "application/octet-stream");
}
if (connection instanceof HttpURLConnection) {
((HttpURLConnection) connection).setChunkedStreamingMode(8192);
}
int size = 0;
output = connection.getOutputStream();
byte[] buffer = new byte[4 * 1024];
for (int count = stream.read(buffer); count != -1; count = stream.read(buffer)) {
output.write(buffer, 0, count);
size += count;
if (m_verbose)
System.out.println("Uploaded bytes... " + size);
}
output.close();
if (connection instanceof HttpURLConnection) {
int responseCode = ((HttpURLConnection) connection).getResponseCode();
String responseMessage = ((HttpURLConnection) connection).getResponseMessage();
switch (responseCode) {
case HttpURLConnection.HTTP_CREATED:
location = connection.getHeaderField("Location");
break;
case HttpURLConnection.HTTP_CONFLICT:
throw new IOException("Resource already exists: " + responseMessage);
case HttpURLConnection.HTTP_INTERNAL_ERROR:
throw new IOException("Internal server error: " + responseMessage);
default:
throw new IOException("Unexpected server response: " + responseMessage);
}
}
}
catch (IOException e) {
throw new IOException("Error importing resource: " + e.getMessage(), e);
}
finally {
if (output != null) {
try {
output.close();
}
catch (Exception ex) {
}
}
}
return new URI(location);
}
}