2013-06-29 8 views
7

私はSwingJPAを統合するためにライブラリを拡張しようとしています。JPAを自動(携帯)として設定すると、プログラムでは<class>の要素が追加されます。 (私はそれがHibernateのAnnotationConfigurationまたはEclipseLInkのServerSessionによって実行可能であることを知っていますが、移植性はあります)。私もSpringをこの目的のためだけに使用しないでください。メモリ内オブジェクトを指すURLを作成することはできますか?

私はpersistence.xmlをオンザフライで作成し、指定したパッケージ(Reflectionsライブラリ経由)の<class>要素で埋め込むことができます。この問題は、このpersistence.xmlJPAプロバイダーにフィードしようとすると開始されます。私が考えることができる唯一の方法は、URLClassLoaderを設定することですが、有効なURLを取得するための唯一の能力のために、どこかでディスクにファイルを書き込ませない方法は考えられません。 URLlocalhost:xxxx)経由でファイルを提供するためのソケットを設定しているようです...私は悪いのか分かりませんか?

この問題をどのように解決できるか考えている人はいますか? 1つのライブラリを使わないようにするのはたくさんの仕事のように聞こえるが、それができるかどうかを知りたいと思う。

EDIT(より明確なものでTRY):

は動的XMLStringオブジェクトに保管されて生成されました。私は永続化プロバイダにそれを利用可能にする方法を知らない。また、ファイルをディスクに書き込まないようにしたいと思います。

私の問題のために、持続性プロバイダは、クラスパスをMETA-INF/persistence.xmlのためにスキャンする単なるクラスです。一部の実装ではXMLの動的作成を受け入れることができますが、共通のインタフェースはありません(特にファイルの重要な部分の場合は<class>タグ)。

私の考えは、カスタムを設定することですClassLoader - あなたが他に感謝したいと思うなら、私はこれに設定されていません。

私が見つけることができる唯一の容易に拡張可能な/設定可能なものはURLClassLoaderでした。 URLオブジェクトで動作します。実際にXMLを最初にディスクに書き込まずに作成できるかどうかはわかりません。

私は物事を設定してい方法です

が、それは、ディスクへのpersistenceXmlFile = new File("META-INF/persistence.xml")書くことによって働いている:

Thread.currentThread().setContextClassLoader(
    new URLResourceClassLoader(
     new URL[] { persistenceXmlFile.toURI().toURL() }, 
     Thread.currentThread().getContextClassLoader() 
    ) 
); 

URLResourceClassLoaderはオーバーライドすることで、リソースだけでなく、クラスを検索することができますURLCLassLoaderのサブクラスであり、 public Enumeration<URL> findResources(String name)

+1

あなたが本当に "[メモリを意味しますかマップされた "](http://en.wikipedia.org/wiki/Memory-mapped_file)、または"メモリ内にのみ存在するオブジェクト? " –

+0

メモリはプロセスごとにプライベートと見なされるので、可能かどうか疑問に思っています。 –

+0

使用しているコードは何ですか?そしてなぜそれはURLでなければならないのですか?コードを表示すると、一般的な 'Resource'やそのようなものをうまく受け入れることができます。 – yair

答えて

3

たぶん(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()); 
       } 

      }; 
     } 

    } 
} 
関連する問題