1 Reply Latest reply on Dec 23, 2009 10:03 AM by kabirkhan

    Supporting OSGi properties via qualifiers

    kabirkhan

      From this discussion: http://community.jboss.org/message/316405#316405

       

      I have taken a look at qualifiers, and it looks like we need to make the qualifier resolution algorithm pluggable.

       

      For example, this would be easy to support

      
      <inject>
       <qualifier type="filter">(a=b)</qualifier>
      </inject>

       

      But looking at org.osgi.framework.Filter, we can have more complicated qualifiers:

       

      An RFC 1960-based Filter.

      Filters can be created by calling BundleContext.createFilter or FrameworkUtil.createFilter with a filter string.

      A Filter can be used numerous times to determine if the match argument matches the filter string that was used to create the Filter.

      Some examples of LDAP filters are:

        "(cn=Babs Jensen)"
        "(!(cn=Tim Howes))"
        "(&(" + Constants.OBJECTCLASS + "=Person)(|(sn=Jensen)(cn=Babs J*)))"
        "(o=univ*of*mich*)"

       

      The current String and Annotation qualifiers are resolved via doing a simple equality check, for LDAP filters we need to make some other kind of check. I will work on making the resolution pluggable in kernel, testing with some mock qualifier types before looking into how to support this from the OSGi side.

       

      The JIRA sub-task: https://jira.jboss.org/jira/browse/JBKERNEL-70

        • 1. Re: Supporting OSGi properties via qualifiers
          kabirkhan

          kabir.khan@jboss.com wrote:

           

          The JIRA sub-task: https://jira.jboss.org/jira/browse/JBKERNEL-70

          The plumbing for supporting new/unanticipated qualifier types has been done in kernel. See BeanQualifiersTestCase.testCustomMatcherAndParser() for an example.

           

          Briefly there is a new package org.jboss.kernel.spi.qualifier:

          QualfierMatchers contains a registry of QualfierMatchers and QualifierParsers

           

          When parsing the qualifier metadata to populate the MDR and the injection point qualifiers, the correct QualifierParser for the QualifierContent type is used.

          • The STRING implementation just returns the original qualifier object
          • The ANNOTATION implementation parses the qualifier object into an annotation

          The parse() methods take reference to a ClassLoader, although I am not using that yet, e.g.;

             Object parseWanted(ClassLoader cl, Object rawQualifier);
          

           

          Next when the matching is done by ClassAndQualifierKey, it iterates over each wanted qualifiers and calls QualifierMatchers:

          public boolean matches(ControllerContext context, Set<Object> suppliedQualifiers, Object qualifier)
          

          qualifier is the wanted qualifier, then we iterate over each context passing in the context and its suppliedQualifiers. Internally this checks the class of the wanted qualifier and uses the corresponding matcher. If no matcher exists for that type, it uses a default implementation which returns true if qualifier exists in suppliedQualifiers.

           

          To do the OSGi property matching I imagine you would do something like:

           

          Create and add a QualifierParser for a PROPERTY content type, which

          • parses supplied qualifiers into a Dictionary
          • parses wanted qualifiers (e.g. "(!(cn=Tim Howes))") into some LdapMatcher

           

          Create and add a QualifierMatcher for LdapMatcher, with a matches() method that iterates over each supplied qualifier and if that is of type Dictionary, check that Dictionary for entries that were specified in the data used to create the LdapMatcher.