package com.dhemery.network; import java.io.*; import java.net.URL; import java.net.URLConnection; /** * A resource accessible through a URL. */ public class URLResource implements Resource { private static final boolean FOR_READING = false; private static final boolean FOR_WRITING = true; private static final int READ_TIMEOUT = 30000; private final URLConnection connection; /** * Create a resource with the specified URL. */ public URLResource(URL url) { connection = connection(url); } @Override public URL url() { return connection.getURL(); } @Override public String get() { connect(FOR_READING); return read(); } @Override public String put(String message) { connect(FOR_WRITING); write(message); return read(); } private static URLConnection connection(URL url) { try { return url.openConnection(); } catch (IOException cause) { throw new NetworkException(url, "Cannot create connection", cause); } } private void connect(boolean forWriting) { try { connection.setDoInput(true); connection.setDoOutput(forWriting); connection.setReadTimeout(READ_TIMEOUT); connection.connect(); } catch (IOException cause) { throw new NetworkException(this, "Cannot connect", cause); } } private void write(String message) { OutputStreamWriter writer = writer(); try { writer.write(message); } catch (IOException cause) { throw new NetworkException(this, "Cannot write", cause); } close(writer); } private OutputStreamWriter writer() { try { return new OutputStreamWriter(connection.getOutputStream()); } catch (IOException cause) { throw new NetworkException(this, "Cannot get output stream", cause); } } private String read() { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream())); StringBuilder builder = new StringBuilder(); String line; while((line = readLine(reader)) != null) { builder.append(line); } close(reader); return builder.toString(); } private InputStream inputStream() { try { return connection.getInputStream(); } catch (IOException cause) { throw new NetworkException(this, "Cannot get input stream", cause); } } private String readLine(BufferedReader reader) { try { return reader.readLine(); } catch (IOException cause) { throw new NetworkException(this, "Cannot read line", cause); } } private void close(Writer writer) { try { writer.close(); } catch (IOException cause) { throw new NetworkException(this, "Cannot close writer", cause); } } private void close(BufferedReader reader) { try { reader.close(); } catch (IOException cause) { throw new NetworkException(this, "Cannot close reader", cause); } } @Override public String toString() { return connection.getURL().toString(); } }