package at.gv.egovernment.moa.spss.server.invoke;
import iaik.ixsil.exceptions.URIException;
import iaik.ixsil.util.URI;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import at.gv.egovernment.moa.spss.MOAApplicationException;
import at.gv.egovernment.moa.spss.server.transaction.TransactionContext;
import at.gv.egovernment.moa.spss.server.transaction.TransactionContextManager;
/**
* Resolve external URIs and provide them as a stream.
*
* @author Patrick Peck
* @version $Id$
*/
public class ExternalURIResolver {
/** The MIME type of the content currently resolved. */
private String contentType;
/**
* Return a stream to data at the given URI.
*
* This method will try to open an URLConnection
to the given
* URI. Access to the file system is disallowed.
*
* @param uriStr The URI to resolve.
* @return InputStream The data contained at the URI.
* @throws MOAApplicationException An error occurred resolving the URI (e.g.,
* the URI is syntactically incorrect or the stream could not be opened).
*/
public InputStream resolve(String uriStr) throws MOAApplicationException {
URI uri;
URL url;
URLConnection connection;
InputStream is;
// build the URI
try {
uri = new URI(uriStr);
} catch (URIException e) {
throw new MOAApplicationException("2207", new Object[] { uriStr });
}
// disallow access to local file system
if ("".equals(uri.getScheme()) || "file".equals(uri.getScheme())) {
throw new MOAApplicationException("2213", new Object[] { uriStr });
}
// if we have local content (SOAP with attachments)
if ("formdata".equals(uri.getScheme())) {
TransactionContext context = TransactionContextManager.getInstance().getTransactionContext();
if (context==null) {
//no transaction
throw new MOAApplicationException("2282", new Object[] { uri });
} else {
InputStream attachmentIs = context.getAttachmentInputStream(uri);
if (attachmentIs != null) {
setContentType(context.getAttachmentContentType(uri.getPath()));
return attachmentIs;
} else {
//maybe attachments provided but no suiting attachment found
throw new MOAApplicationException("2282", new Object[] { uri });
}
/*
try {
InputStream attachmentIs = context.getAttachment(uri).getInputStream();
if (attachmentIs != null) {
setContentType(context.getAttachmentContentType(uri.getPath()));
return attachmentIs;
} else {
//maybe attachments provided but no suiting attachment found
throw new MOAApplicationException("2282", new Object[] { uri });
}
} catch (IOException e) {
throw new MOAApplicationException("2208", new Object[] { uri }, e);
}
*/
}
}
// convert URI to URL
try {
// create the URL
url = new URL(uriStr);
} catch (MalformedURLException e) {
throw new MOAApplicationException("2214", new Object[] { uriStr });
}
// build the URLConnection
try {
connection = url.openConnection();
if ("http".equals(url.getProtocol())) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
httpConnection.connect();
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new MOAApplicationException("2208", new Object[] { uri });
}
} else if ("https".equals(url.getProtocol())) {
/*
* this doesn't work because of some interaction between the IAIK
* JCE and Sun JSSE that results in an "Invalid AVA format" exception
*/
/*
HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
InputStream trustStore =
getClass().getResourceAsStream(DEFAULT_TRUST_STORE);
SSLSocketFactory factory =
SSLUtils.getSSLSocketFactory("jks", trustStore, "changeit");
httpsConnection.setSSLSocketFactory(factory);
httpsConnection.connect();
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new MOAApplicationException("2208", new Object[] { uri });
}
*/
connection.connect();
} else {
connection.connect();
}
is = connection.getInputStream();
} catch (IOException e) {
throw new MOAApplicationException("2208", new Object[] { uri }, e);
} /*catch (GeneralSecurityException e) {
throw new MOAApplicationException("2208", new Object[] { uri }, e);
}*/
// set the content type
setContentType(connection.getContentType());
return is;
}
/**
* Set the content type of the data at the URI.
*
* @param contentType The content type to set.
*/
protected void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* Return the content type of the data detected at the URI from the previous
* call of resolve()
.
*
* @return String The content type.
*/
public String getContentType() {
return contentType;
}
}