2009-07-21 25 views
7

Tôi đang phát triển một ứng dụng bằng OSGi (nền tảng Equinox) và một trong các gói cần phân tích các tệp XML. Cho đến nay tôi đã thực hiện điều này với SAX (javax.xml.parsers.SAXParserFactory) và tôi muốn lấy SAXParserFactory từ nền tảng này.Sử dụng triển khai phân tích cú pháp XML dưới dạng dịch vụ OSGi

Tôi thấy tiêu chuẩn OSGi cung cấp cho một XMLParserActivator để cho phép triển khai JAXP tự đăng ký (http://www.osgi.org/javadoc/r4v41/org/osgi/util/xml/XMLParserActivator.html), do đó, tôi đoán là có một số gói cung cấp SAXParserFactory như một dịch vụ.

Tuy nhiên, tôi không thể tìm ra gói nào sẽ thêm làm phụ thuộc để tìm dịch vụ cung cấp SAXParserFactory. Tôi cố gắng để lấy một tài liệu tham khảo phục vụ sử dụng

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

Cho rằng XML phân tích cú pháp là một điều khá phổ biến để làm, tôi cho rằng có những triển khai có sẵn, hoặc các phương tiện khác để có được một dịch vụ phân tích cú pháp XML từ nền tảng này.

Mọi trợ giúp sẽ rất được hoan nghênh!

+0

Hi, Tôi không tự tin với OSGi nhưng tại sao không sử dụng ngăn xếp XML kèm với JRE? – ATorras

+0

Xin chào, có, nhưng cơ chế trình nạp lớp OSGi khác - và do đó gọi SAXParserFactory.newInstance() có thể mang lại các vấn đề, vì cơ chế trình tải JAXP hy vọng sẽ tìm thấy trình phân tích cú pháp trong trình nạp lớp của luồng hiện tại và có thể không nhất thiết phải là trường hợp . –

Trả lời

3

Nói chung, không nên sử dụng JAXP trong OSGi (vì cơ chế tải lớp chủ yếu) và ý tưởng tốt hơn để có được nhà máy giống như một dịch vụ.

Nếu bạn đang sử dụng phân, các SaxParserFactory (bằng cách sử dụng một JRE/JDK bạn đang chạy trên) là thực sự được cung cấp bởi hệ thống Bundle, có nghĩa là bạn không cần phải thêm bó:

{javax.xml .parsers.SAXParserFactory} = {service.id = 6} Được đăng ký bởi gói: Gói hệ thống [0]

Nếu bạn muốn viết mã liên quan đến lớp vòng đời của nền tảng OSGi, tôi sẽ đề xuất theo dõi tham khảo, thay vì tìm kiếm trực tiếp. Có nhiều cách tiếp cận cho việc này; Tôi đã viết về một trong những tôi gọi ServiceMediator here.

ví dụ: đối với trường hợp của bạn (mã là dưới Apache 2 Giấy phép, Coalevo dự án):

 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

Tôi cũng khuyên bạn nên xem "OSGI Dynamic Services" hoặc "Spring DM" cả hai đều có phương tiện tương tự để khai báo/giải quyết các phụ thuộc của một gói được khai báo. Và với những cơ chế này, mã ở trên sẽ đơn giản hóa đáng kể. –

+0

Đoạn mã trên không thực sự phức tạp và có thể dễ dàng được tạo ra bằng máy (Chốt có thể lấy từ những nơi khác nhau nếu cần thiết cho Môi trường Thời gian chạy). Tôi không nghi ngờ rằng DS (tôi giả định rằng bạn tham khảo Dịch vụ Tuyên bố) là một thay thế, tuy nhiên, bạn cũng có thể kết thúc với một số tập tin cấu hình khá phức tạp đôi khi. Dù sao, bạn luôn có lựa chọn thay thế để chọn từ :) – Dieter

-1

Bạn có thể sử dụng Apache Xerces để phân tích cú pháp Sax. Một gói phù hợp có sẵn từ Eclipse Orbit project. Tôi không biết rằng gói Xerces đăng ký dịch vụ SAXParserFactory nhưng bạn có thể thêm một phụ thuộc vào gói và sử dụng trình phân tích cú pháp Sax trực tiếp.

+0

Tránh các gói phụ thuộc bất cứ khi nào có thể. – brindy

Các vấn đề liên quan