// Copyright 2013 Michel Kraemer
//
// Licensed 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 de.undercouch.citeproc.helper;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

/**
 * Utilities for the CSL processor
 * @author Michel Kraemer
 */
public class CSLUtils {
	/**
	 * Reads a string from a URL
	 * @param u the URL
	 * @param encoding the character encoding
	 * @return the string
	 * @throws IOException if the URL contents could not be read
	 */
	public static String readURLToString(URL u, String encoding) throws IOException {
		return readStreamToString(u.openStream(), encoding);
	}
	
	/**
	 * Reads a string from a file.
	 * @param f the file
	 * @param encoding the character encoding
	 * @return the string
	 * @throws IOException if the file contents could not be read
	 */
	public static String readFileToString(File f, String encoding) throws IOException {
		return readStreamToString(new FileInputStream(f), encoding);
	}
	
	/**
	 * Reads a string from a stream. Closes the stream after reading.
	 * @param is the stream
	 * @param encoding the character encoding
	 * @return the string
	 * @throws IOException if the stream contents could not be read
	 */
	public static String readStreamToString(InputStream is, String encoding) throws IOException {
		try {
			StringBuilder sb = new StringBuilder();
			byte[] buf = new byte[1024 * 10];
			int read;
			while ((read = is.read(buf)) >= 0) {
				sb.append(new String(buf, 0, read, encoding));
			}
			return sb.toString();
		} finally {
			is.close();
		}
	}
	
	/**
	 * Reads a byte array from a URL
	 * @param url the URL
	 * @return the byte array
	 * @throws IOException if the URL contents could not be read
	 */
	public static byte[] readURL(URL url) throws IOException {
		return readStream(url.openStream());
	}
	
	/**
	 * Reads a byte array from a stream. Closes the stream after reading.
	 * @param is the stream
	 * @return the byte array
	 * @throws IOException if the stream contents could not be read
	 */
	public static byte[] readStream(InputStream is) throws IOException {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			byte[] buf = new byte[1024 * 10];
			int read;
			while ((read = is.read(buf)) >= 0) {
				baos.write(buf, 0, read);
			}
			return baos.toByteArray();
		} finally {
			is.close();
		}
	}
}

@@ -788,19 +788,85 @@
 ava.net.
-URL
+HttpURLConnection;%0Aimport java.net.URL;%0Aimport java.net.URLConnection
 ;%0A%0A/**%0A 
@@ -1217,32 +1217,590 @@
 s IOException %7B%0A
+%09%09for (int i = 0; i %3C 30; ++i) %7B%0A%09%09%09URLConnection conn = u.openConnection();%0A%0A%09%09%09// handle HTTP URLs%0A%09%09%09if (conn instanceof HttpURLConnection) %7B%0A%09%09%09%09HttpURLConnection hconn = (HttpURLConnection)conn;%0A%0A%09%09%09%09// set timeouts%0A%09%09%09%09hconn.setConnectTimeout(15000);%0A%09%09%09%09hconn.setReadTimeout(15000);%0A%0A%09%09%09%09// handle redirects%0A%09%09%09%09switch (hconn.getResponseCode()) %7B%0A%09%09%09%09case HttpURLConnection.HTTP_MOVED_PERM:%0A%09%09%09%09case HttpURLConnection.HTTP_MOVED_TEMP:%0A%09%09%09%09%09String location = hconn.getHeaderField(%22Location%22);%0A%09%09%09%09%09u = new URL(u, location);%0A%09%09%09%09%09continue;%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%0A%09
 %09%09return readStr
@@ -1811,22 +1811,29 @@
 oString(
-u.open
+conn.getInput
 Stream()
@@ -1837,36 +1837,92 @@
 m(), encoding);%0A
+%09%09%7D%0A%0A%09%09throw new IOException(%22Too many HTTP redirects%22);%0A
 %09%7D%0A
-%09
 %0A%09/**%0A%09 * Reads 

Allow styles to be loaded from HTTP URLs