Tapestry
  1. Tapestry
  2. TAPESTRY-2519

Make ClassNameLocatorImpl resolve resources from URLs that use a client-defined protocol

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 5.0.14
    • Fix Version/s: 5.0.14
    • Component/s: None
    • Labels:
      None

      Description

      ClassNameLocatorImpl is only able to resolve resources from URLs that use a protocol which is native to the Java class library (file, jar, http, etc). In OSGi environment all the URLs use the protocol "bundleresource" or "bundleentry". Here is an example:

      bundleresource://5642/org/apache/tapestry5/corelib/pages/

      A very simple solution is to create your own ClassNameLocator and contribute it to AliasOverrides. Well, this solution is bad because it requires a copy of the ClassNameLocatorImpl.

      A better solution would be to make ClassNameLocatorImpl use a service called URLConverter or similar.

      public interface URLConverter
      {
      URL convert(URL url);
      }

      Tapestry would provide a default implementation of the interface:

      public class URLConverterImpl implements URLConverter
      {
      public URL convert(URL url)

      { return url; }

      }

      In an OSGi environment (in my case Equinox) one could override this service by using e.g Eclipse Core API. This approach is much easier then overriding of the ClassNameLocator.

        Activity

        Hide
        Igor Drobiazko added a comment -

        If the converter is not able to convert it should return the original url. The osgi converter would convert the url into native jar or file urls. We could also allow the converter to be chained. In this case returning of null would make sense. This way the next converter in the chain could try to convert. By default Tapestry would put only one converter into this chain.

        ClassNameLocator is already a service. It is absolutely no problem to override it. The problem is how to do it. The new implementation of ClassNameLocator will need the most code of the original implementation. Only a small part needs to be overridden. So it makes sense to extend ClassNameLocatorImpl and replace it.The problem is that ClassNameLocatorImpl was not designed for extension. It is not possible to extend it by overriding one of the methods. That's why I suggested to use the converter service.

        Show
        Igor Drobiazko added a comment - If the converter is not able to convert it should return the original url. The osgi converter would convert the url into native jar or file urls. We could also allow the converter to be chained. In this case returning of null would make sense. This way the next converter in the chain could try to convert. By default Tapestry would put only one converter into this chain. ClassNameLocator is already a service. It is absolutely no problem to override it. The problem is how to do it. The new implementation of ClassNameLocator will need the most code of the original implementation. Only a small part needs to be overridden. So it makes sense to extend ClassNameLocatorImpl and replace it.The problem is that ClassNameLocatorImpl was not designed for extension. It is not possible to extend it by overriding one of the methods. That's why I suggested to use the converter service.
        Hide
        Howard M. Lewis Ship added a comment -

        So, does convert() return null if it can't convert? I do like the idea of splitting the logic up a little bit. It's also looking like ClassNameLocator should become a service, rather than a utility, to support overrides and decoration. Can you document what convert() is exactly supposed to do? Convert from a OSGi bundle URL to a native jar: or file: URL?

        Show
        Howard M. Lewis Ship added a comment - So, does convert() return null if it can't convert? I do like the idea of splitting the logic up a little bit. It's also looking like ClassNameLocator should become a service, rather than a utility, to support overrides and decoration. Can you document what convert() is exactly supposed to do? Convert from a OSGi bundle URL to a native jar: or file: URL?
        Hide
        Igor Drobiazko added a comment -

        Nope, this modification is supposed to be resolve classes whose URLs are different from those Tapestry is able to resolve. That's all. ModuleDef on its part is responsible for embedding services into Tapestry that are binded outside the AppModule. Since in OSGi we also have a bunch of service we may contribute the OSGi services to Tapestry by using the ModuleDefs.

        Show
        Igor Drobiazko added a comment - Nope, this modification is supposed to be resolve classes whose URLs are different from those Tapestry is able to resolve. That's all. ModuleDef on its part is responsible for embedding services into Tapestry that are binded outside the AppModule. Since in OSGi we also have a bunch of service we may contribute the OSGi services to Tapestry by using the ModuleDefs.
        Hide
        Massimo Lusetti added a comment -

        I ask if this modifications could be used as bridge for spring integration too instead of the current way, which is the implementation of ModuleDef[] provideExtraModuleDefs(ServletContext context) inside the TapestrySpringFilter.

        Regards.

        Show
        Massimo Lusetti added a comment - I ask if this modifications could be used as bridge for spring integration too instead of the current way, which is the implementation of ModuleDef[] provideExtraModuleDefs(ServletContext context) inside the TapestrySpringFilter. Regards.
        Hide
        Igor Drobiazko added a comment -

        What exactly do you mean?

        Show
        Igor Drobiazko added a comment - What exactly do you mean?
        Hide
        Massimo Lusetti added a comment -

        Does this could affect the way tapestry-spring is made?

        Show
        Massimo Lusetti added a comment - Does this could affect the way tapestry-spring is made?

          People

          • Assignee:
            Howard M. Lewis Ship
            Reporter:
            Igor Drobiazko
          • Votes:
            3 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development