Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions src/main/java/com/github/sardine/Sardine.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ List<DavResource> list(String url, int depth, boolean allProp)
*/
void put(String url, InputStream dataStream) throws IOException;

/**
* Uses <code>PUT</code> to send data to a server. Not repeatable on authentication failure.
*
* @param url Path to the resource including protocol and hostname
* @param writeLogic a callback executed executed to perform the write to the resource
* @throws IOException I/O error or HTTP response validation failure
*/
void put(String url, WriteLogic writeLogic) throws IOException;

/**
* Uses <code>PUT</code> to send data to a server with a specific content type
* header. Repeatable on authentication failure.
Expand Down Expand Up @@ -214,10 +223,21 @@ List<DavResource> list(String url, int depth, boolean allProp)
* @throws IOException I/O error or HTTP response validation failure
*/
void put(String url, InputStream dataStream, Map<String, String> headers) throws IOException;


/**
* Uses <code>PUT</code> to send data to a server with specific headers. Not repeatable
* on authentication failure.
*
* @param url Path to the resource including protocol and hostname
* @param writeLogic a callback executed executed to perform the write to the resource
* @param headers Additional HTTP headers to add to the request
* @throws IOException I/O error or HTTP response validation failure
*/
void put(String url, WriteLogic writeLogic, Map<String, String> headers) throws IOException;

/**
* Uses <code>PUT</code> to upload file to a server with specific contentType.
* Repeatable on authentication failure.
* Repeatable on authentication failure.
*
* @param url Path to the resource including protocol and hostname
* @param localFile local file to send
Expand Down
14 changes: 14 additions & 0 deletions src/main/java/com/github/sardine/WriteLogic.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.sardine;

import java.io.IOException;
import java.io.OutputStream;

/**
* Callback to perform logic to write to an output stream.
*
* @author trejkaz
*/
public interface WriteLogic
{
void withOutputStream(OutputStream stream) throws IOException;
}
59 changes: 44 additions & 15 deletions src/main/java/com/github/sardine/impl/SardineImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.github.sardine.DavResource;
import com.github.sardine.Sardine;
import com.github.sardine.Version;
import com.github.sardine.WriteLogic;
import com.github.sardine.impl.handler.ExistsResponseHandler;
import com.github.sardine.impl.handler.LockResponseHandler;
import com.github.sardine.impl.handler.MultiStatusResponseHandler;
Expand Down Expand Up @@ -234,8 +235,8 @@ public void setCredentials(String username, String password)
@Override
public void setCredentials(String username, String password, String domain, String workstation)
{
this.context.setCredentialsProvider(this.getCredentialsProvider(username, password, domain, workstation));
this.context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, new AuthState());
this.context.setCredentialsProvider(this.getCredentialsProvider(username, password, domain, workstation));
this.context.setAttribute(HttpClientContext.TARGET_AUTH_STATE, new AuthState());
}

private CredentialsProvider getCredentialsProvider(String username, String password, String domain, String workstation)
Expand Down Expand Up @@ -744,6 +745,13 @@ public void put(String url, InputStream dataStream) throws IOException
this.put(url, dataStream, (String) null);
}

@Override
public void put(String url, WriteLogic writeLogic) throws IOException
{
WriteLogicEntity entity = new WriteLogicEntity(writeLogic);
this.put(url, entity, (String) null, true);
}

@Override
public void put(String url, InputStream dataStream, String contentType) throws IOException
{
Expand All @@ -765,13 +773,25 @@ public void put(String url, InputStream dataStream, String contentType, boolean
}

@Override
public void put(String url, InputStream dataStream, Map<String, String> headers) throws IOException {
List<Header> list = new ArrayList<Header>();
for(Map.Entry<String, String> h: headers.entrySet()) {
list.add(new BasicHeader(h.getKey(), h.getValue()));
}
this.put(url, dataStream, list);
}
public void put(String url, InputStream dataStream, Map<String, String> headers) throws IOException
{
this.put(url, dataStream, headerMapToList(headers));
}

@Override
public void put(String url, WriteLogic writeLogic, Map<String, String> headers) throws IOException
{
this.put(url, writeLogic, headerMapToList(headers));
}

private List<Header> headerMapToList(Map<String, String> map)
{
List<Header> list = new ArrayList<Header>();
for(Map.Entry<String, String> h: map.entrySet()) {
list.add(new BasicHeader(h.getKey(), h.getValue()));
}
return list;
}

public void put(String url, InputStream dataStream, List<Header> headers) throws IOException
{
Expand All @@ -780,6 +800,12 @@ public void put(String url, InputStream dataStream, List<Header> headers) throws
this.put(url, entity, headers);
}

public void put(String url, WriteLogic writeLogic, List<Header> headers) throws IOException
{
WriteLogicEntity entity = new WriteLogicEntity(writeLogic);
this.put(url, entity, headers);
}

/**
* Upload the entity using <code>PUT</code>
*
Expand Down Expand Up @@ -844,12 +870,15 @@ public <T> T put(String url, HttpEntity entity, List<Header> headers, ResponseHa
throw e;
}
}
@Override
public void put(String url, File localFile, String contentType) throws IOException {
FileEntity content = new FileEntity(localFile);
//don't use ExpectContinue for repetable FileEntity, some web server (IIS for exmaple) may return 400 bad request after retry
this.put(url, content, contentType, false);
}

@Override
public void put(String url, File localFile, String contentType) throws IOException
{
FileEntity content = new FileEntity(localFile);
//don't use ExpectContinue for repetable FileEntity, some web server (IIS for exmaple) may return 400 bad request after retry
this.put(url, content, contentType, false);
}

@Override
public void delete(String url) throws IOException
{
Expand Down
71 changes: 71 additions & 0 deletions src/main/java/com/github/sardine/impl/WriteLogicEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.github.sardine.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.ContentType;

import com.github.sardine.WriteLogic;

/**
* <p>An entity which performs writing using an instance of {@link WriteLogic}.</p>
*
* <p>Calls to {@code getContent()} will fail and this class can only be used when making requests
* (but that's the only time that its use makes any kind of sense.)</p>
*
* @author trejkaz
*/
class WriteLogicEntity extends AbstractHttpEntity
{
private final WriteLogic writeLogic;

WriteLogicEntity(WriteLogic writeLogic)
{
this(writeLogic, null);
}

WriteLogicEntity(WriteLogic writeLogic, ContentType contentType)
{
this.writeLogic = writeLogic;
if (contentType != null)
{
this.setContentType(contentType.toString());
}
}

@Override
public boolean isRepeatable()
{
// Playing it safe.
return false;
}

@Override
public long getContentLength()
{
// Because we can't possibly know.
return -1L;
}

@Override
public InputStream getContent() throws IOException
{
// Supposedly this is OK, but the API hasn't formalised it yet:
// http://stackoverflow.com/questions/10146692/how-do-i-write-to-an-outputstream-using-defaulthttpclient
throw new UnsupportedOperationException("getContent() not supported, use writeTo(OutputStream) instead");
}

@Override
public void writeTo(OutputStream outputStream) throws IOException
{
writeLogic.withOutputStream(outputStream);
}

@Override
public boolean isStreaming()
{
// Still not sure what the right value is here.
return false;
}
}