2009-07-21 6 views
7

OSGi(Equinoxプラットフォーム)を使用してアプリケーションを開発しており、バンドルの1つがXMLファイルを解析する必要があります。これまでSAX(javax.xml.parsers.SAXParserFactory)で実装したので、プラットフォームからSAXParserFactoryを取得したいと考えています。OSGiサービスとしてのXMLパーサー実装の使用

OSGi標準では、JAXP実装が自分自身(http://www.osgi.org/javadoc/r4v41/org/osgi/util/xml/XMLParserActivator.html)を登録できるようにXMLParserActivatorが用意されていることがわかったので、SAXParserFactoryをサービスとして提供するバンドルがいくつかあるはずです。

しかし、SAXParserFactoryを提供するサービスを見つけるために、どのバンドルを依存関係として追加するかわかりませんでした。私は、XMLの構文解析を行うにはかなり一般的なものであることを考えると

context.getServiceReferences(SAXParserFactory.class.getName(), "(&(parser.namespaceAware=true)(parser.validating=true))") 

を使用してサービスの参照を取得しようと、私は利用可能な実装、または他の手段は、プラットフォームからXMLパーササービスを得るためにそこにあるとします。

どのようなヘルプも大歓迎です!

+0

こんにちは、 私は、OSGiと自信を持ってないんだけど、なぜJREにバンドルXMLスタックを使用していませんか? – ATorras

+0

JAXPローダ・メカニズムが現在のスレッド・クラス・ローダーにパーサを見つけることを期待しているため、OSGiクラス・ローダー・メカニズムが異なります。したがって、SAXParserFactory.newInstance()を呼び出すと問題が発生する可能性があります。 。 –

答えて

3

OSGiでJAXPを使用するのは良い考えではありません(主にクラスローディングのメカニズムが原因です)、工場をサービスのようにするより良いアイデアです。

あなたは春分を使用している場合は、(あなたが上で実行されているJRE/JDKのいずれかを使用)のSAXParserFactoryが実際にあなたが余分なバンドルを必要としないことを意味する、システムバンドルで提供されています

{javax.xml .parsers.SAXParserFactory} = {service.id = 6} バンドルで登録:システムバンドル[0]

OSGiプラットフォームのライフサイクルレイヤを扱うコードを記述したい場合は、参照する必要はありません。 これには多くのアプローチがあります。私はServiceMediatorをhereと呼んでいます。

あなたのケース(コードは、Apache 2ライセンス、Coalevoプロジェクトの下にある)のために:

 import org.osgi.framework.*; 

    import javax.xml.parsers.SAXParserFactory; 

    import net.wimpi.telnetd.util.Latch; 

    /** 
    * Implements a mediator pattern class for services from the OSGi container. 
    * <p/> 
    * 
    * @author Dieter Wimberger (wimpi) 
    * @version @[email protected] (@[email protected]) 
    */ 
    class ServiceMediator { 

     private BundleContext m_BundleContext; 

     private SAXParserFactory m_SAXParserFactory; 
     private Latch m_SAXParserFactoryLatch; 

     public SAXParserFactory getSAXParserFactory(long wait) { 
     try { 
      if (wait < 0) { 
      m_SAXParserFactoryLatch.acquire(); 
      } else if (wait > 0) { 
      m_SAXParserFactoryLatch.attempt(wait); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(System.err); 
     } 

     return m_SAXParserFactory; 
     }//getSAXParserFactory 

     public boolean activate(BundleContext bc) { 
     //get the context 
     m_BundleContext = bc; 

     m_SAXParserFactoryLatch = createWaitLatch(); 

     //prepareDefinitions listener 
     ServiceListener serviceListener = new ServiceListenerImpl(); 

     //prepareDefinitions the filter 
     String filter = "(objectclass=" + SAXParserFactory.class.getName() + ")"; 

     try { 
      //add the listener to the bundle context. 
      bc.addServiceListener(serviceListener, filter); 

      //ensure that already registered Service instances are registered with 
      //the manager 
      ServiceReference[] srl = bc.getServiceReferences(null, filter); 
      for (int i = 0; srl != null && i < srl.length; i++) { 
      serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, srl[i])); 
      } 
     } catch (InvalidSyntaxException ex) { 
      ex.printStackTrace(System.err); 
      return false; 
     } 
     return true; 
     }//activate 

     public void deactivate() { 
     m_SAXParserFactory = null; 

     m_SAXParserFactoryLatch = null; 

     m_BundleContext = null; 
     }//deactivate 

     private Latch createWaitLatch() { 
     return new Latch(); 
     }//createWaitLatch 

     private class ServiceListenerImpl 
      implements ServiceListener { 

     public void serviceChanged(ServiceEvent ev) { 
      ServiceReference sr = ev.getServiceReference(); 
      Object o = null; 
      switch (ev.getType()) { 
      case ServiceEvent.REGISTERED: 
       o = m_BundleContext.getService(sr); 
       if (o == null) { 
       return; 
       } else if (o instanceof SAXParserFactory) { 
       m_SAXParserFactory = (SAXParserFactory) o; 
       m_SAXParserFactory.setValidating(false); 
       m_SAXParserFactory.setNamespaceAware(true); 
       m_SAXParserFactoryLatch.release(); 
       } else { 
       m_BundleContext.ungetService(sr); 
       } 
       break; 
      case ServiceEvent.UNREGISTERING: 
       o = m_BundleContext.getService(sr); 
       if (o == null) { 
       return; 
       } else if (o instanceof SAXParserFactory) { 
       m_SAXParserFactory = null; 
       m_SAXParserFactoryLatch = createWaitLatch(); 
       } else { 
       m_BundleContext.ungetService(sr); 
       } 
       break; 
      } 
     } 
     }//inner class ServiceListenerImpl 

     public static long WAIT_UNLIMITED = -1; 
     public static long NO_WAIT = 0; 

    }//class ServiceMediator 
+0

「OSGI Dynamic Services」または「Spring DM」を参照することもお勧めします。 バンドルの宣言/依存関係を宣言的に宣言/解決するための同様の手段を持っています。そして、これらのメカニズムによって、上記のコードはかなり単純化されます。 –

+0

上記のコードは実際に複雑ではなく、簡単に機械で生成することができます(ランタイム環境で必要な場合は、さまざまな場所から取得できます)。 DS(Declarative Servicesを参照していると仮定していると仮定しています)が選択肢であることは疑いありませんが、かなり複雑な設定ファイルで終わることもあります。 とにかく、それから選ぶための選択肢を持つことは常に良いです:) – Dieter

-1

Apache XercesをSax解析用に使用できます。適切なバンドルはEclipse Orbit projectから入手できます。 XercesバンドルがSAXParserFactoryサービスを登録しているが、バンドルに依存関係を追加してSaxパーサーを直接使用することはできません。

+0

可能な場合は、バンドルの依存関係を避けてください。 – brindy

関連する問題