6 Replies Latest reply on Oct 1, 2008 10:58 AM by alesj

    Federated resource visitor

    alesj

      In order to impl Seam's tight integration with existing JBoss5/MC AnnotationEnvironment / ResourceVisitor (RV) pattern:
      - https://jira.jboss.org/jira/browse/JBAS-6012
      I need a sort of federated resource visitor - in order not to visit same resources many times.

      e.g. with Seam deployment I would need to check for
      - annotations (we already do this via GenericAnnotationRV)
      - different configuration files; xmls, .properties, ...
      hence requiring RV per resource.

      I've hacked this FederatedVFSVR:

       protected boolean acceptRecurseFilter(VirtualFile file)
       {
       if (recurseFilters == null || recurseFilters.length == 0)
       return true;
      
       String path = determinePath(file);
       ResourceContext resource = new VFSResourceContext(file, path, getClassLoader());
       boolean accept = false;
       for (int j = 0; j < recurseFilters.length; j++)
       {
       recurseFlags[j] = recurseFilters[j] == null || recurseFilters[j].accepts(resource);
       if (recurseFlags[j]) // one accepts it
       accept = true;
       }
       return accept;
       }
      
       public void visit(VirtualFile file)
       {
       try
       {
       // We don't want directories
       if (file.isLeaf() == false)
       return;
      
       // Determine the resource name
       String path = determinePath(file);
       // go over the true flags
       for (int j = 0; j < visitors.length; j++)
       {
       if (recurseFlags == null || recurseFlags.length <= i || recurseFlags[j])
       {
       // Check for inclusions/exclusions
       if (includeds != null && includeds.length > j && includeds[j] != null && includeds[j].matchesResourcePath(path) == false)
       continue;
       if (excludeds != null && excludeds.length > j && excludeds[j] != null && excludeds[j].matchesResourcePath(path))
       continue;
      
       ResourceContext resource = new VFSResourceContext(file, path, getClassLoader());
       //Check the filter and visit
       if (filters == null || filters.length <= j || filters[j] == null || filters[j].accepts(resource))
       visitors[j].visit(resource);
       }
       }
       }
       catch (Exception e)
       {
       throw new Error("Error visiting " + file, e);
       }
       }
      


      But I would need to somehow enable its usage in VFSClassLoaderPolicyModule,
      where we actually 'hit' the Module.

      Should I again expand Module::visit method,
      to take multiple visitors, filters, recurseFilters?
      Back-porting the old behavior to call the old non-federated single VFS VR.


        • 1. Re: Federated resource visitor
          alesj

           

          "alesj" wrote:

          But I would need to somehow enable its usage in VFSClassLoaderPolicyModule,
          where we actually 'hit' the Module.

          Should I again expand Module::visit method,
          to take multiple visitors, filters, recurseFilters?
          Back-porting the old behavior to call the old non-federated single VFS VR.

          Or I could actually revert things,
          implementing federated versions of RV and ResourceFilter.
          Let me check how this works out.

          • 2. Re: Federated resource visitor
            alesj

             

            "alesj" wrote:

            Or I could actually revert things,
            implementing federated versions of RV and ResourceFilter.
            Let me check how this works out.

            Yup, this looks much better approach,
            since it doesn't require me to change anything.

            I'll just impl federated version of RV,
            which will also serve as a holder for recurseFilter,
            since I need to know if recurse filter refused to accept given file.


            • 3. Re: Federated resource visitor

              I don't understand what you are doing.

              The JIRA issue talks about ResourceLookup and you say

              hence requiring RV per resource.
              

              why wouldn't it just use use Class(Loader).getResource(s)
              why do you need a complicated visitor for this?

              • 4. Re: Federated resource visitor
                alesj

                 

                "adrian@jboss.org" wrote:

                I don't understand what you are doing.

                Federated or group resource visitor. ;-)

                e.g. I have different / multiple resource visitors and their matching filters / recurse filters
                And I would like to run them all on the same module.
                I could do it either
                - visit module n times
                - visit module only once, but apply RVs as they match along the visit path

                Which do you like more? :-)

                "adrian@jboss.org" wrote:

                The JIRA issue talks about ResourceLookup and you say
                hence requiring RV per resource.
                

                why wouldn't it just use use Class(Loader).getResource(s)
                why do you need a complicated visitor for this?

                Since I'm already visiting Seam's classpath for annotations,
                why shouldn't I build that metadata along the way,
                instead of doing additional n lookups for different Seam resources.

                And this way I can use regexp or (name-your-waaaay-better-matching-strategy-here-than-CL-findResource) to get the matching resources. ;-)


                • 5. Re: Federated resource visitor

                  My question was, why do you need to do any complex visiting/caching when
                  the plain old classloading api does the job required.
                  i.e. You know the resource path(s) up front so a lookup is more efficient

                  It's not like classes which has no ClassLoader.getClassNames()
                  and even it did, you want to cache/index the annotations once anyway.

                  • 6. Re: Federated resource visitor
                    alesj

                     

                    "adrian@jboss.org" wrote:
                    My question was, why do you need to do any complex visiting/caching when
                    the plain old classloading api does the job required.
                    i.e. You know the resource path(s) up front so a lookup is more efficient

                    IIRC they have some mechanism to override things
                    depending on the file/classname.
                    e.g. FooBar.class --> FooBar.component.xml
                    Similar to what Hibernate did/does with .hbm.xml.

                    And since I'm already so 'close' to FooBar class (doing @Name inspection),
                    why don't I also read overriden xml part (if it exists)?
                    Instead of remembering which are Seam components,
                    and then doing CL:findResource lookup for possible override.
                    Eventually implementing some custom ResourceContext (RC) to generically
                    read that found resource.
                    Where I could simply use existing RC with all fancy hooks - getBytes, getInputStream, ...

                    And afaik they also have a need for other suffix / regexp matching resources,
                    e.g. -page.xml (or something similar).
                    This would allow to place resources anywhere in classpath,
                    making it possible for users to group some stuff.

                    But in general, thinking about the federated stuff,
                    I'm surprised it didn't pop-up before.
                    e.g. doing @annotation read + some other class inspection on the same Module,
                    while still keeping things separated by what they do, not what they match