javaserverfaces-spec-public
  1. javaserverfaces-spec-public
  2. JAVASERVERFACES_SPEC_PUBLIC-1143

[jsr344] FaceletCache and FaceletFactory requires special methods to deal with composite components.

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: Facelets/VDL
    • Labels:
      None

      Description

      In JSF 2.1, FaceletCache API was added, defining 2 types of facelets:

      • Normal facelet: This is a facelet that was retrieved parsing files as usual. FaceletCache provide these methods:

      public abstract V getFacelet(URL url) throws IOException;

      public abstract boolean isFaceletCached(URL url);

      • View metadata facelet: This is a facelet that trim all content outside f:metadata. It is used to calculate the view metadata without build the whole view (GET requests). FaceletCache provide these methods:

      public abstract V getViewMetadataFacelet(URL url) throws IOException;

      public abstract boolean isViewMetadataFaceletCached(URL url);

      But composite components requires also to calculate metadata. Right now in Mojarra, this step:

      ViewDeclarationLanguage.getComponentMetadata(FacesContext context, Resource componentResource)

      Is done using a norma facelet, but in MyFaces, since our implementation is bound to facelets template engine it is necessary an alternate facelet, to allow calculate the component metadata quickly, like with view metadata facelets.

      This note was added in MyFaces implementation by myself about FaceletCacheImpl long time ago:

      • TODO: Note MyFaces core has another type of Facelet for read composite component
      • metadata. The reason behind do this in MyFaces is to retrieve some information
      • related to insertChildren/insertFacet that can be used as metadata and use that
      • information later to do the hack for composite components using templates, instead
      • rely on component relocation. This is not handled by FaceletCache included here
      • but in practice this should not be a problem, because the intention of this class
      • is handle Facelet instances created using custom ResourceResolver stuff, and
      • usually those pages are for views, not for composite components. Even if that is
      • true, composite component metadata Facelet is smaller (only add cc:xxx stuff) that
      • the other ones used for views or the one used to apply the composite component
      • itself.

      The problem is with the introduction in JSF 2.2 of FaceletFactory, this flaw becomes more evident, because we also have special methods in FaceletFactory to deal with composite components:

      public abstract class FaceletFactory

      { /** * Return a Facelet instance as specified by the file at the passed URI. The returned facelet is used * to create composite component metadata. * <p> * This method should be called from vdl.getComponentMetadata(FacesContext context) * </p> * * @since 2.0.1 * @param uri * @return * @throws IOException */ public abstract Facelet getCompositeComponentMetadataFacelet(String uri) throws IOException; /** * Create a Facelet used to create composite component metadata from the passed URL. This method checks if the * cached Facelet needs to be refreshed before returning. If so, uses the passed URL to build a new instance. * * @since 2.0.1 * @param url source url * @return Facelet instance * @throws IOException * @throws FaceletException * @throws FacesException * @throws ELException */ public abstract Facelet getCompositeComponentMetadataFacelet(URL url) throws IOException, FaceletException, FacesException, ELException; }

      Since in JSF 2.2 the intention is expose FaceletFactory:

      http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-611

      this implementation detail becomes relevant, because MyFaces needs to differentiate between a Facelet that creates composite component metadata and a normal facelet. It is more, there is no way to implement composite component spec using facelets template engine like MyFaces does without this detail.

      The solution is add these methods to FaceletFactory:

      public abstract Facelet getCompositeComponentMetadataFacelet(String uri) throws IOException;

      public abstract Facelet getCompositeComponentMetadataFacelet(URL url)
      throws IOException, FaceletException, FacesException, ELException;

      and add these methods to FaceletCache:

      public V getCompositeComponentMetadataFacelet(URL url) throws IOException;

      public boolean isCompositeComponentMetadataFaceletCached(URL url);

      protected FaceletCache.MemberFactory<V> getCompositeComponentMetadataMemberFactory()

      and update the code properly. Without this change, implementations of FaceletFactory and FaceletCache will work only for Mojarra, and remember the idea of the spec is provide an API that can support different implementations. Really this is a big issue for us to be fixed in the spec before include FaceletFactory into the spec.

        Activity

        Hide
        Ed Burns added a comment -

        Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.

        Show
        Ed Burns added a comment - Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.
        Hide
        Manfred Riem added a comment -

        Setting priority to Minor

        Show
        Manfred Riem added a comment - Setting priority to Minor

          People

          • Assignee:
            Unassigned
            Reporter:
            lu4242
          • Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: