trivial protocol handler for strings?

B

bugbear

My application is currently configured by giving it
a URL pointing to complex config data (which is in XML,
and parsed using Xerces).

For Testing (JUnit) purposes, I would very much like
to be able to throw small (going on tiny) configs
around.

So I have come up with the idea of using a trivial
protocol (e.g. "string:") where the URL *itself*
is (or contains?) the data.

Thus, if I had some config data in configString

private final String configString =
"<?xml version='1.0' encoding='UTF-8' ?>" +
"<config>" +
"<config_elem name=\"henry\">" +
" <other_elem>" +
" </other_elem>" +
"</config_elem" +
"</config>";

I would like to do:

URL url = "string:" + escapeForURL(configString);

And have a suitable ("string:") protocol handler take over in
the "real" code, and give access to an InputStream
formed from the String.

Has anyone else already done this?
The learning curve looks pretty steep to me:
http://java.sun.com/developer/onlineTraining/protocolhandlers/

BugBear
 
M

Matt Parker

bugbear said:
My application is currently configured by giving it
a URL pointing to complex config data (which is in XML,
and parsed using Xerces).

For Testing (JUnit) purposes, I would very much like
to be able to throw small (going on tiny) configs
around.

So I have come up with the idea of using a trivial
protocol (e.g. "string:") where the URL *itself*
is (or contains?) the data.

Thus, if I had some config data in configString

private final String configString =
"<?xml version='1.0' encoding='UTF-8' ?>" +
"<config>" +
"<config_elem name=\"henry\">" +
" <other_elem>" +
" </other_elem>" +
"</config_elem" +
"</config>";

I would like to do:

URL url = "string:" + escapeForURL(configString);

And have a suitable ("string:") protocol handler take over in
the "real" code, and give access to an InputStream
formed from the String.

Has anyone else already done this?
The learning curve looks pretty steep to me:
http://java.sun.com/developer/onlineTraining/protocolhandlers/

BugBear

Hi BugBear,

Have you tried java.net.URLEncoder.encode() then convert the String to a
byte array and use a ByteArrayInputStream? Or am I getting completely the
wrong end of the stick here.

Matt
 
M

Matt Parker

BTW, you don't work at Engage anymore. Perhaps you ought to change your
e-mail address...

Matt
 
C

Chris Uppal

bugbear said:
So I have come up with the idea of using a trivial
protocol (e.g. "string:") where the URL *itself*
is (or contains?) the data.

I got interested in this, it sounds like a handy thing to have around. It's
not too hard to do, just two fairly simple classes.

This is largely untested, and probably a bit *too* simple about the way it
handles response headers and character encodings, but it's a start. Elaborate
at will ;-)

-- chris

==========
package org.metagnostic.net.protocol.string;

/*
Simple "string:" protocol.
Copyright Chris Uppal

To use this, set the system property "java.protocol.handler.pkgs" to
include this
class's package in the |-separated list, eg:

java -Djava.protocol.handler.pkgs=org.metagnostic.net.protocol
MyProgram

Then use a String URL like:

string:eek:ne+two%20three

which will have an input stream that "contains" (as bytes)

one two three

NB: the package name *must* end in ".string", and the classname *must* be
Handler,
since that is how protocol handlers are recognised by the Java runtime.
*/

import java.net.*;


public class Handler
extends java.net.URLStreamHandler
{
public static final String PROTOCOL_NAME = "string";

public URLConnection
openConnection(URL url)
{
return new StringURLConnection(url);
}

protected int
getDefaultPort()
{
return 0;
}

protected void
parseURL(URL url, String spec, int start, int limit)
{
String content;

try
{
// very simplistic
content = spec.substring(PROTOCOL_NAME.length() + 1);
content = URLDecoder.decode(content, "UTF-8");
}
catch (java.io.UnsupportedEncodingException e)
{
// I can't be arsed...
content = e.toString();
}

setURL(
url,
PROTOCOL_NAME, // protocol
null, // host
getDefaultPort(), // port
null, // authority
null, // user info
content, // path
null, // query
null); // ref
}

protected String
toExternalForm(URL url)
{
String content;

try
{
// very simplistic
content = PROTOCOL_NAME + ":" + URLEncoder.encode(url.getPath(),
"UTF-8");
}
catch (java.io.UnsupportedEncodingException e)
{
// I still can't be arsed...
content = e.toString();
}

return PROTOCOL_NAME + ":" + content;
}
}
==========
package org.metagnostic.net.protocol.string;

/*
Simple "string:" protocol.
Copyright Chris Uppal
*/

import java.util.*;
import java.io.*;

public class StringURLConnection
extends java.net.URLConnection
{
private InputStream inputStream;
private final Map headers;
private final String theString;

public StringURLConnection(java.net.URL url)
{
super(url);

// content is stored as "path" by Handler.parseURL()
theString = url.getPath();

headers = new HashMap();
}

public void
connect()
{
if (connected)
return;
connected = true;

headers.put("content-length", "" + theString.length());
headers.put("content-type", "text/plain");
byte[] bytes = theString.getBytes(); // default charset
inputStream = new ByteArrayInputStream(bytes);
}

public InputStream
getInputStream()
{
connect();
return inputStream;
}

public String
getHeaderField(String name)
{
connect();
return (String)headers.get(name);
}

public Map
getHeaderFields()
{
connect();
return Collections.unmodifiableMap(headers);
}
}
==========
 
R

Roedy Green

I got interested in this, it sounds like a handy thing to have around. It's
not too hard to do, just two fairly simple classes.

ordinary urls have the CGI parameters for encoding data fields.

Years ago we did a project where we added new URL types. I don't
recall how it worked.
 
C

Chris Uppal

Roedy said:
ordinary urls have the CGI parameters for encoding data fields.

Hi Roedy, I've only just noticed this post. I'm not sure what you are getting
at here, are you pointing out something I've done wrong in the "string:"
protocol handler ?

-- chris
 
R

Roedy Green

Hi Roedy, I've only just noticed this post. I'm not sure what you are getting
at here, are you pointing out something I've done wrong in the "string:"
protocol handler ?

I have not seen your code. It was not clear if you were reinventing
the wheel with your own parameter encoding method.
 
C

Chris Uppal

Roedy said:
I have not seen your code.

?? It was in the post you quoted in your reply ??
It was not clear if you were reinventing
the wheel with your own parameter encoding method.

No, no. Nothing like that.

Thanks for replying.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top