Is it possible to create an URL pointing to an in
I'm trying to extend my library for integrating Swing
and JPA
by making JPA
config as automatic (and portable) as can be done, and it means programmatically adding <class>
elements. (I know it can be done via Hibernate's AnnotationConfiguration
or EclipseLInk's ServerSession
, but - portability). I'd also like to avoid using Spring
just for this single purpose.
I can create a persistence.xml
on the fly, and fill it with <class>
elements from specified packages (via the Reflections library). The problem starts when I try to feed this persistence.xml
to a JPA
provider. The only way I can think of is setting up a URLClassLoader
, but I can't think of a way what wouldn't make me write the file to the disk somewhere first, for sole ability to obtain a valid URL
. Setting up a socket for serving the file via an URL
( localhost:xxxx
) seems... I don't know, evil?
Does anyone have an idea how I could solve this problem? I know it sounds like a lot of work to avoid using one library, but I'd just like to know if it can be done.
EDIT (a try at being more clear):
Dynamically generated XML
is kept in a String
object. I don't know how to make it available to a persistence provider. Also, I want to avoid writing the file to disk.
For purpose of my problem, a persistence provider is just a class which scans the classpath for META-INF/persistence.xml
. Some implementations can be made to accept dynamic creation of XML
, but there is no common interface (especially for a crucial part of the file, the <class>
tags).
My idea is to set up a custom ClassLoader
- if you have any other I'd be grateful, I'm not set on this one.
The only easily extendable/configurable one I could find was a URLClassLoader
. It works on URL
objects, and I don't know if I can create one without actually writing XML to disk first.
That's how I'm setting things up, but it's working by writing the persistenceXmlFile = new File("META-INF/persistence.xml")
to disk:
Thread.currentThread().setContextClassLoader(
new URLResourceClassLoader(
new URL[] { persistenceXmlFile.toURI().toURL() },
Thread.currentThread().getContextClassLoader()
)
);
URLResourceClassLoader
is URLCLassLoader
's subclass, which allows for looking up resources as well as classes, by overriding public Enumeration<URL> findResources(String name)
.
也许有点晚(4年后),但对于其他正在寻找类似解决方案的用户,您可以使用我创建的URL工厂:
public class InMemoryURLFactory {
public static void main(String... args) throws Exception {
URL url = InMemoryURLFactory.getInstance().build("/this/is/a/test.txt", "This is a test!");
byte[] data = IOUtils.toByteArray(url.openConnection().getInputStream());
// Prints out: This is a test!
System.out.println(new String(data));
}
private final Map<URL, byte[]> contents = new WeakHashMap<>();
private final URLStreamHandler handler = new InMemoryStreamHandler();
private static InMemoryURLFactory instance = null;
public static synchronized InMemoryURLFactory getInstance() {
if(instance == null)
instance = new InMemoryURLFactory();
return instance;
}
private InMemoryURLFactory() {
}
public URL build(String path, String data) {
try {
return build(path, data.getBytes("UTF-8"));
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
public URL build(String path, byte[] data) {
try {
URL url = new URL("memory", "", -1, path, handler);
contents.put(url, data);
return url;
} catch (MalformedURLException ex) {
throw new RuntimeException(ex);
}
}
private class InMemoryStreamHandler extends URLStreamHandler {
@Override
protected URLConnection openConnection(URL u) throws IOException {
if(!u.getProtocol().equals("memory")) {
throw new IOException("Cannot handle protocol: " + u.getProtocol());
}
return new URLConnection(u) {
private byte[] data = null;
@Override
public void connect() throws IOException {
initDataIfNeeded();
checkDataAvailability();
// Protected field from superclass
connected = true;
}
@Override
public long getContentLengthLong() {
initDataIfNeeded();
if(data == null)
return 0;
return data.length;
}
@Override
public InputStream getInputStream() throws IOException {
initDataIfNeeded();
checkDataAvailability();
return new ByteArrayInputStream(data);
}
private void initDataIfNeeded() {
if(data == null)
data = contents.get(u);
}
private void checkDataAvailability() throws IOException {
if(data == null)
throw new IOException("In-memory data cannot be found for: " + u.getPath());
}
};
}
}
}
链接地址: http://www.djcxy.com/p/72474.html
上一篇: 创建一个新的自定义列
下一篇: 是否可以创建指向in的URL?