/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.codebase;
import java.io.BufferedInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import org.whole.lang.bindings.IBindingManager;
/**
* @author Riccardo Solmi, Enrico Persiani
*/
public class URLPersistenceProvider extends AbstractPersistenceProvider {
private URL url;
public URLPersistenceProvider(URL url) {
this(url, null);
}
public URLPersistenceProvider(URL url, IBindingManager bm) {
super(bm);
this.url = url;
}
public URL getStore() {
return url;
}
public InputStream openInputStream() throws Exception {
URLConnection connection = url.openConnection();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
int code = httpConnection.getResponseCode();
if (code != HttpURLConnection.HTTP_OK)
throw new IOException("unexpected HTTP response code " + code);
parseHeaders(httpConnection);
}
InputStream is = connection.getInputStream();
return is.markSupported() ? is : new BufferedInputStream(is);
}
public OutputStream openOutputStream() throws Exception {
URLConnection connection = url.openConnection();
if (connection instanceof HttpURLConnection) {
String mediaType = getBindings().wIsSet("mediaType") ?
getBindings().wStringValue("mediaType") : "text/plain";
final HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("PUT");
httpConnection.setDoOutput(true);
httpConnection.setRequestProperty("Content-Type", mediaType+";charset="+getEncoding());
OutputStream outputStream = httpConnection.getOutputStream();
return new FilterOutputStream(outputStream) {
public void close() throws IOException {
super.close();
int code = httpConnection.getResponseCode();
if (code != HttpURLConnection.HTTP_OK &&
code != HttpURLConnection.HTTP_CREATED &&
code != HttpURLConnection.HTTP_NO_CONTENT)
throw new IOException("unexpected HTTP response code " + code);
};
};
} else
return connection.getOutputStream();
}
public boolean exists() {
if (head() == null)
try {
openInputStream().close();
} catch (Exception e) {
return false;
}
return true;
}
public Date getLastModified() throws IOException {
HttpURLConnection connection = head();
if (connection == null)
throw new IOException("missing resource");
long millis = connection.getLastModified();
return new Date(millis == 0L ?System.currentTimeMillis(): millis);
}
public long getContentLength() throws IOException {
HttpURLConnection connection = head();
if (connection == null)
throw new IOException("missing resource");
return connection.getContentLength();
}
public boolean delete() throws Exception {
URLConnection connection = url.openConnection();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("DELETE");
int code = httpConnection.getResponseCode();
return code == HttpURLConnection.HTTP_OK || code == HttpURLConnection.HTTP_ACCEPTED
|| code == HttpURLConnection.HTTP_NO_CONTENT;
}
return false;
}
protected void parseHeaders(HttpURLConnection httpConnection) {
String mediaType = null;
String contentType = httpConnection.getContentType();
int indexOfSemicolon = contentType.indexOf(';');
if (indexOfSemicolon != -1) {
mediaType = contentType.substring(0, indexOfSemicolon).trim();
String parameter = contentType.substring(indexOfSemicolon+1).trim();
if (parameter.startsWith("charset="))
withDefaultEncoding(parameter.substring(parameter.indexOf('=')+1).trim());
} else
mediaType = contentType.trim();
getBindings().wDefValue("mediaType", mediaType);
}
protected HttpURLConnection head() {
try {
URLConnection connection = url.openConnection();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.setRequestMethod("HEAD");
if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK)
return httpConnection;
}
} catch (Exception e) {
}
return null;
}
}