2013-06-29 6 views
7

मैं Swing और JPA को JPA कॉन्फ़िगरेशन के रूप में स्वचालित (और पोर्टेबल) के रूप में बनाने के द्वारा अपनी लाइब्रेरी को विस्तारित करने का प्रयास कर रहा हूं, और इसका अर्थ है प्रोग्रामेटिक रूप से <class> तत्व जोड़ना। (मुझे पता है कि यह हाइबरनेट के AnnotationConfiguration या एक्लेप्सेलिंक के ServerSession, लेकिन पोर्टेबिलिटी के माध्यम से किया जा सकता है)। मैं सिर्फ इस उद्देश्य के लिए Spring का उपयोग करना टालना चाहूंगा।क्या एक मेमोरी ऑब्जेक्ट को इंगित करने वाला यूआरएल बनाना संभव है?

मैं फ्लाई पर persistence.xml बना सकता हूं, और निर्दिष्ट पैकेजों (प्रतिबिंब पुस्तकालय के माध्यम से) <class> तत्वों के साथ भर सकता हूं। समस्या तब शुरू होती है जब मैं persistence.xml को JPA प्रदाता को फ़ीड करने का प्रयास करता हूं। एकमात्र तरीका जिस पर मैं सोच सकता हूं वह URLClassLoader स्थापित कर रहा है, लेकिन मैं इस तरह से नहीं सोच सकता कि मुझे डिस्क को फ़ाइल को पहले कहीं लिखने के लिए नहीं, एक वैध URL प्राप्त करने की एकमात्र क्षमता के लिए। URL (localhost:xxxx) के माध्यम से फ़ाइल की सेवा के लिए सॉकेट सेट करना प्रतीत होता है ... मुझे नहीं पता, बुराई?

क्या किसी को पता है कि मैं इस समस्या को कैसे हल कर सकता हूं? मुझे पता है कि यह एक पुस्तकालय का उपयोग करने से बचने के लिए बहुत सारे काम की तरह लगता है, लेकिन मुझे यह जानना है कि यह किया जा सकता है या नहीं।

संपादित (और अधिक स्पष्ट किया जा रहा है पर एक कोशिश):

डायनामिक रूप से जेनरेट XML एक String वस्तु में रखा है। मुझे नहीं पता कि इसे दृढ़ता प्रदाता पर कैसे उपलब्ध कराया जाए। इसके अलावा, मैं डिस्क को फ़ाइल लिखने से बचना चाहता हूं।

मेरी समस्या के उद्देश्य के लिए, दृढ़ता प्रदाता केवल एक वर्ग है जो META-INF/persistence.xml के लिए क्लासपाथ स्कैन करता है। XML की गतिशील रचना को स्वीकार करने के लिए कुछ कार्यान्वयन किए जा सकते हैं, लेकिन कोई आम इंटरफ़ेस नहीं है (विशेष रूप से फ़ाइल के एक महत्वपूर्ण भाग के लिए, <class> टैग)।

मेरा विचार कस्टम ClassLoader सेट अप करना है - यदि आपके पास कोई अन्य है तो मैं आभारी हूं, मैं इस पर सेट नहीं हूं।

एकमात्र आसानी से विस्तार योग्य/कॉन्फ़िगर करने योग्य मुझे मिल सकता है URLClassLoader। यह URL ऑब्जेक्ट्स पर काम करता है, और मुझे नहीं पता कि मैं वास्तव में डिस्क पर एक्सएमएल लिखने के बिना एक बना सकता हूं या नहीं।

कैसे मैं चीजों को सेट कर रहा हूं है कि है, लेकिन यह डिस्क पर persistenceXmlFile = new File("META-INF/persistence.xml") लिख कर काम कर रहा है:

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

URLResourceClassLoaderURLCLassLoader के उपवर्ग, जो संसाधनों के साथ ही वर्गों को देख, अधिभावी द्वारा के लिए अनुमति देता है public Enumeration<URL> findResources(String name)

+1

आप वास्तव में मतलब है [ "स्मृति मैप किया गया "] (http://en.wikipedia.org/wiki/Memory-mapped_file), या क्या आपका मतलब है" एक वस्तु जो केवल स्मृति में मौजूद है? " –

+0

मुझे यह भी आश्चर्य है कि यह संभव है, क्योंकि स्मृति को प्रति प्रक्रिया निजी माना जाता है ... –

+0

आप जिस कोड का उपयोग कर रहे हैं? और यह यूआरएल क्यों होना चाहिए?यदि आप कोड दिखाएंगे तो हम ऐसे समाधान के साथ आ सकते हैं जो कुछ सामान्य 'संसाधन' या इस तरह से स्वीकार करता है। – 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()); 
       } 

      }; 
     } 

    } 
} 
संबंधित मुद्दे