package org.infernus.idea.checkstyle.model;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jetbrains.annotations.NotNull;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
/**
* A configuration file accessible via a HTTP URL.
*/
public class HTTPURLConfigurationLocation extends ConfigurationLocation {
private static final Log LOG = LogFactory.getLog(HTTPURLConfigurationLocation.class);
private static final int CONTENT_CACHE_SECONDS = 2;
private static final int ONE_SECOND = 1000;
private byte[] cachedContent;
private long cacheExpiry;
HTTPURLConfigurationLocation() {
super(ConfigurationType.HTTP_URL);
}
HTTPURLConfigurationLocation(final ConfigurationType configurationType) {
super(configurationType);
}
@NotNull
protected InputStream resolveFile() throws IOException {
if (cachedContent != null && cacheExpiry > System.currentTimeMillis()) {
return new ByteArrayInputStream(cachedContent);
}
try {
cachedContent = asBytes(connectionTo(getLocation()));
cacheExpiry = System.currentTimeMillis() + (CONTENT_CACHE_SECONDS * ONE_SECOND);
return new ByteArrayInputStream(cachedContent);
} catch (IOException e) {
LOG.info("Couldn't read URL: " + getLocation(), e);
cachedContent = null;
cacheExpiry = 0;
throw e;
}
}
@NotNull
URLConnection connectionTo(final String location) throws IOException {
final URL url = new URL(location);
final URLConnection urlConnection = url.openConnection();
urlConnection.setDoInput(true);
urlConnection.setDoOutput(false);
urlConnection.setAllowUserInteraction(false);
addBasicAuth(url, urlConnection);
return urlConnection;
}
private void addBasicAuth(final URL url, final URLConnection urlConnection) {
if (url.getUserInfo() != null) {
urlConnection.setRequestProperty("Authorization",
"Basic " + DatatypeConverter.printBase64Binary(url.getUserInfo().getBytes()));
}
}
private byte[] asBytes(final URLConnection urlConnection) throws IOException {
urlConnection.connect();
final ByteArrayOutputStream responseBody = new ByteArrayOutputStream();
try (Writer writer = new BufferedWriter(new OutputStreamWriter(responseBody));
Reader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))) {
int readChar;
while ((readChar = reader.read()) != -1) {
writer.write(readChar);
}
writer.flush();
return responseBody.toByteArray();
}
}
@Override
public Object clone() {
return cloneCommonPropertiesTo(new HTTPURLConfigurationLocation());
}
}