// $Id: DataStreamHandler.java,v 1.9 2009-05-01 13:25:59 jim Exp $ /* This code is released as public domain: you are free to use it in any way that you want. */ package org.faceless.util; import java.io.*; import java.net.*; import org.faceless.util.Base64InputStream; import org.faceless.util.Base64OutputStream; /** * A URLStreamHandler for the data URL * scheme. Factory is combined into this class for simplicity. * * Can't rely on this unfortunately, as at least WebLogic uses it's own streamhandlerfactory */ public class DataStreamHandler extends URLStreamHandler { public int getDefaultPort() { return -1; } public InetAddress getHostAddress(URL url) { return null; } public URLConnection openConnection(final URL url) { return new URLConnection(url) { public void connect() { } public InputStream getInputStream() { String path = this.url.getPath(); int i = path.indexOf(","); String data = path.substring(i+1); boolean base64 = path.substring(0, i).endsWith(";base64"); try { if (base64) { return new Base64InputStream(new ByteArrayInputStream(data.getBytes("US-ASCII"))); } else { return new FilterInputStream(new ByteArrayInputStream(data.getBytes("US-ASCII"))) { public int read() throws IOException { int c = super.read(); if (c=='%') { c = (Integer.parseInt(""+((char)super.read()), 16)<<4) + Integer.parseInt(""+((char)super.read()), 16); // Character.toString() is a 1.4 feature, can't use } return c; } }; } } catch (IOException e) { throw new Error("No US-ASCII encoding"); } } public String getContentType() { String type = this.url.getPath(); type = type.substring(0, type.indexOf(",")); if (type.endsWith(";base64")) { type = type.substring(0, type.length()-7); } return type.length()==0 ? "text/plain;charset=US-ASCII" : type; } }; } /** * Return a factory creating objects of this type */ public static final URLStreamHandlerFactory createFactory() { return new URLStreamHandlerFactory() { public URLStreamHandler createURLStreamHandler(String protocol) { return protocol.equalsIgnoreCase("data") ? new DataStreamHandler() : null; } }; } /** * Create a data URL for the specified object * @param data the data to embed in the URL * @param mimetype the MIME-type of the data * @return a "data:" URL */ public static final String encode(byte[] data, String mimetype) { try { final StringBuffer sb = new StringBuffer((data.length/3*4)+mimetype.length()+8); sb.append("data:"); sb.append(mimetype); sb.append(";base64,"); OutputStream out = new OutputStream() { public void write(int c) { sb.append((char)(c&0xFF)); } }; Base64OutputStream fout = new Base64OutputStream(out, false); fout.write(data); fout.close(); return sb.toString(); } catch (IOException e) { RuntimeException e2 = new RuntimeException(e.getMessage()); try { e2.initCause(e); } catch (Throwable e3) { } throw e2; } } /* public static void main(String[] args) throws Exception { URL.setURLStreamHandlerFactory(createFactory()); // String urlstring = encode("This is a test".getBytes("ISO-8859-1"), "text/plain"); String urlstring = "data:image/png;base64,"+ "iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABGdBTUEAALGP"+ "C/xhBQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9YGARc5KB0XV+IA"+ "AAAddEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAAF1J"+ "REFUGNO9zL0NglAAxPEfdLTs4BZM4DIO4C7OwQg2JoQ9LE1exdlYvBBeZ7jq"+ "ch9//q1uH4TLzw4d6+ErXMMcXuHWxId3KOETnnXXV6MJpcq2MLaI97CER3N0"+ "vr4MkhoXe0rZigAAAABJRU5ErkJggg=="; URLConnection con = new URL(urlstring).openConnection(); System.err.println("Content-type: "+con.getContentType()); InputStream in = con.getInputStream(); OutputStream out = System.out; int c; while ((c=in.read())>=0) { out.write(c); } out.flush(); } */ }