Pluto
  1. Pluto
  2. PLUTO-509

JAXB portlet descriptor model handling broken with respect to the different namespace handling for portlet API 1.0 and 2.0

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.0-refactoring, 2.0.0
    • Fix Version/s: 2.0-refactoring, 2.0.0-M1, 2.0.0
    • Component/s: descriptor
    • Labels:
      None

      Description

      The current Portlet 1.0 and Portlet 2.0 JAXB descriptor api is an ackward merge of both namespaces in one object model.
      While this did seem to "work" more or less correct, when testing it more thoroughly it complete blew to pieces ...

      JAXB really cannot properly handle two namespaces blended on top of a single object model, it uses java packaging to map namespaces.
      And while you can have multiple fields mapped to multiple namespaces in one bean, one cannot do the same with one class: you really need to duplicate the classes to support multiple namespaces.
      This really becomes clear as soon as you try to actually write out an JAXB managed object tree.
      Using the current Pluto descriptor mapping this simply isn't possible to do without a corrupting the output or just exceptions thrown all over the place.

      So, as we do need to have this managed properly, I have started out rewriting the whole JAXB mapping mostly from scratch again, now properly using two implementation packages for the two namespaces (portlet10 and portlet20).

      As we already had extracted the descriptor api interfaces, the two new implementation packages both implement the most common denominator (e.g. portlet20) interface, where the portlet10 implementations throw an UnsupportedOperationException when trying to use portlet20 specific features (write and read methods).

      As the JAXB jxc compiler generates classes based on the xsd type definitions, all *DD classes ended up to be called *Type now. I've kept it that way as the *DD classes are no longer directly used anyway (or at least shouldn't).

      Finally, to be able to modify an JAXB loaded portlet10 or portlet20 descriptor model, while only dealing with the interfaces, a solution is needed for creating new instances of objects managed through lists, e.g. portletApp.getPortlets().add(Portlet).
      For this purpose, I've created a new ElementFactoryList<E> extending ArrayList<E> which provides a factory method for creating new elements for itself: E ElementFactoryList<E>.newElement().
      So, like for a org.apache.pluto.om.portlet.Portlet interface, you have to use: portletApp.getPortlets().add(portletApp.getPortlets().newElement()).

        Activity

        Hide
        Ate Douma added a comment -

        I'd like to mention an important observation I made while refactoring the JAXB implementation classes properly:

        The current implementation is not portlet 2.0 spec compliant, and based upon an outdated draft version...

        For one, multi-langual support for Descriptor, DisplayName, etc. elements is not present, only a single description/displayName etc. is possible.
        Portlet expirationCache definition was simplified near the end of specification period, but the current Pluto model still is based on the no longer valid old construct.
        CustomPortalMode still has a decorationName field while that is no longer present in the final model.
        EventDefinition model really is out-of-sync with the final xsd.
        ...

        All the above issues are resolved by generation clean set of JAXB implementation classes based upon the final portlet-app_2_0.xsd

        Show
        Ate Douma added a comment - I'd like to mention an important observation I made while refactoring the JAXB implementation classes properly: The current implementation is not portlet 2.0 spec compliant, and based upon an outdated draft version... For one, multi-langual support for Descriptor, DisplayName, etc. elements is not present, only a single description/displayName etc. is possible. Portlet expirationCache definition was simplified near the end of specification period, but the current Pluto model still is based on the no longer valid old construct. CustomPortalMode still has a decorationName field while that is no longer present in the final model. EventDefinition model really is out-of-sync with the final xsd. ... All the above issues are resolved by generation clean set of JAXB implementation classes based upon the final portlet-app_2_0.xsd
        Hide
        Ate Douma added a comment -

        Done

        Show
        Ate Douma added a comment - Done
        Hide
        David Jencks added a comment -

        If the object models are consistent enough so that they can implement the same interfaces used by pluto itself I'd expect that you could use the 2.0 jaxb tree and simply use a sax filter to change the namespace for portlet 1.0 to that for portlet 2.0 as its being read in. Openejb does this a lot to read in any ejb deployment descriptor into the same jaxb model. If you're interested in pursuing this please point me to the xsds and code that reads a descriptor into jaxb.

        Show
        David Jencks added a comment - If the object models are consistent enough so that they can implement the same interfaces used by pluto itself I'd expect that you could use the 2.0 jaxb tree and simply use a sax filter to change the namespace for portlet 1.0 to that for portlet 2.0 as its being read in. Openejb does this a lot to read in any ejb deployment descriptor into the same jaxb model. If you're interested in pursuing this please point me to the xsds and code that reads a descriptor into jaxb.
        Hide
        Ate Douma added a comment -

        Hi David,

        The problem wasn't so much the reading in (which mostly worked OK, not 100% though), but the writing back out. JAXB has no proper way of telling which namespace and/or fields to use if you mix them together onto the same object model.
        I've already rewritten it from scratch into two separate packages (mapping onto their xsd namespace) with one interface implemented by both and this works nicely now.

        Show
        Ate Douma added a comment - Hi David, The problem wasn't so much the reading in (which mostly worked OK, not 100% though), but the writing back out. JAXB has no proper way of telling which namespace and/or fields to use if you mix them together onto the same object model. I've already rewritten it from scratch into two separate packages (mapping onto their xsd namespace) with one interface implemented by both and this works nicely now.
        Hide
        Ate Douma added a comment -

        Reopening as the pluto container implementation actually requires that at runtime the descriptor model is portlet 2.0 based... even when a portlet 1.0 descriptor was loaded.

        So, going to a third rewrite here, now providing a even more clean om interface api with now only 1 single implementation for the portlet 2.0.
        For the portlet 1.0 descriptors, still a separate JAXB "struct" classes are used, but only for loading now.
        If a portlet 1.0 model was loaded, it will be automatically "upgraded" to a full blown 2.0 model which implements the api interfaces.
        And, for writing out, this can be done in reverse if the application version is still 1.0

        Show
        Ate Douma added a comment - Reopening as the pluto container implementation actually requires that at runtime the descriptor model is portlet 2.0 based... even when a portlet 1.0 descriptor was loaded. So, going to a third rewrite here, now providing a even more clean om interface api with now only 1 single implementation for the portlet 2.0. For the portlet 1.0 descriptors, still a separate JAXB "struct" classes are used, but only for loading now. If a portlet 1.0 model was loaded, it will be automatically "upgraded" to a full blown 2.0 model which implements the api interfaces. And, for writing out, this can be done in reverse if the application version is still 1.0
        Hide
        Ate Douma added a comment -

        Finally fixed properly

        Show
        Ate Douma added a comment - Finally fixed properly

          People

          • Assignee:
            Ate Douma
            Reporter:
            Ate Douma
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development