myfaces-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Gerhard Petracek" <gerhard.petra...@gmail.com>
Subject Re: [Skinning] Independent skinning myfaces subproject
Date Tue, 09 Dec 2008 14:31:12 GMT
hello matthias,

ok - i just asked, because wcag tests failed.

regards,
gerhard



2008/12/9 Matthias Wessendorf <matzew@apache.org>

> On Tue, Dec 9, 2008 at 2:23 PM, Gerhard Petracek
> <gerhard.petracek@gmail.com> wrote:
> > hello,
> >
> > concerning the accessibility mode: is trinidad tested with real
> > screen-readers?
>
> we use jaws
>
> > furthermore, we should specify if we are talking about skinning or
> theming.
> >
> > regards,
> > gerhard
> >
> >
> >
> > 2008/12/9 Paul Rivera <paul_mrivera@yahoo.com>
> >>
> >> Hi,
> >>
> >> I agree with Jeanne as well regarding the requirements.  This has been
> the
> >> list of requirements we've used as a guide in building the skinning
> >> project.  Maybe we can use this as a starting point.  Feel free to
> modify
> >> the list.
> >>
> >> from trinidad:
> >> * basic css style skinning
> >> * global styles/aliases
> >> * skin extensions
> >> * skin additions for custom component developers
> >> * properties skinning
> >> * icon skinning
> >> * text skinning / translations
> >>   - using bundle-name
> >>   - using translation-source
> >> * skin variants based on:
> >>   - agent name
> >>   - agent version
> >>   - platform name
> >>   - accessibility-profile
> >>   - direction (:rtl)
> >>   - locale (@locale, :lang) -> Accdg to the skinning guide, this is not
> >> yet implemented in trinidad
> >> * dynamically changing skins at runtime
> >> * compressed styleclass names feature
> >> * CHECK_FILE_MODIFICATION feature
> >> * And as Jeanne mentioned, compatibility with portals.  I don't have
> much
> >> experience with portals.  I will probably need to look more into this.
> >>
> >> added requirements:
> >> * tomahawk-support: make use of AddResource and ExtensionsFilter
> >> * generic-support
> >>
> >> As for simon's issue on style class / property / icon access strategy
> >> (sub-issue 3.1), I've read somewhere that hashcode is already cached in
> >> String since java 1.3.  I've not really verified this on java 1.3.  But
> I
> >> did check on jdk 1.6 and confirmed that it does cache hashcode.  Here's
> the
> >> snippet fro java.lang.String:
> >>
> >>     public int hashCode() {
> >>     int h = hash;
> >>     if (h == 0) {
> >>         int off = offset;
> >>         char val[] = value;
> >>         int len = count;
> >>
> >>             for (int i = 0; i < len; i++) {
> >>                 h = 31*h + val[off++];
> >>             }
> >>             hash = h;
> >>         }
> >>         return h;
> >>     }
> >>
> >> Best Regards,
> >> Paul Rivera
> >>
> >> --- On Tue, 12/9/08, Matthias Wessendorf <matzew@apache.org> wrote:
> >>
> >> From: Matthias Wessendorf <matzew@apache.org>
> >> Subject: Re: [Skinning] Independent skinning myfaces subproject
> >> To: "MyFaces Development" <dev@myfaces.apache.org>
> >> Date: Tuesday, December 9, 2008, 12:52 AM
> >>
> >> On Tue, Dec 9, 2008 at 1:03 AM, Jeanne Waldman
> >> <jeanne.waldman@oracle.com> wrote:
> >> >
> >>  What about Step A - requirements? We should list out the requirements
> we
> >> > have so we can make sure we aren't missing anything. There's been
> >> a lot of
> >> > work in getting the skinning to work with portals, so we'll need that
> >>
> >> to
> >> > still work and we will probably want to redesign it since it's kind of
> >> lame
> >> > the way it works right now.
> >>
> >> +1
> >> good point, Jeanne, we don't want to see that work destroyed.
> >>
> >> -M
> >>
> >>
> >> >
> >> > From my experience coming up with a good API takes a lot of time. I'll
> >> try
> >> > to find some time to read your proposal at least.
> >> >
> >> > Jeanne
> >> >
> >> > Simon Lessard wrote, On 12/8/2008 6:16 AM PT:
> >>
> >> >>
> >> >> I would prefer a roadmap like:
> >> >>
> >> >>   1. Design a modular API that fits Trinidad's needs with minimal
> >> >>      compatibility loss.
> >> >>   2. In parallel
> >> >>         1. Start implementing the API defined in 1.
> >>  as a myfaces
> >> >>            extension, possibily along with a ResourceHandler for JSF
> >> 1.2
> >> >>       2. Propose the API to JSF 2.0 EG
> >> >>   3. If the API make it the the spec then
> >> >>         1. Convert the extension to fit the new API (even if target
> >>
> >> >>            is 1.2 it should be possible but in a different package)
> >> >>         2. Integrate the API with the corect package naming to the
> >> >>            2.0 branch (obviously)
> >> >>   4. In the API doesn't get in the spec, then create a 2.0 branch
> >>
> >> of
> >> >>      the skin extension
> >> >>   5. Convert Trinidad to the new extension
> >> >>   6. Integrate the extension in Tomahawk and Tobago
> >> >>
> >> >>
> >> >> So, for now, I would really really like to get comments from the
> >>
> >> community
> >> >> on the API I proposed as well as potential solutions for the
> pendings.
> >> >> Otherwise I'll have to
> >>  propose it in its current form and that
> >> would prevent
> >> >> the API to be reviewed by the MyFaces community and that would be a
> >> shame
> >> >> imho. As I mentioned before, time is running really short and the
> fact
> >>
> >> that
> >> >> 2.0 is in public review phase alone might prevent the addition of
> such
> >> core
> >> >> API in the spec so the faster we can design a great API, the more
> >> chances
> >> >> there is to see it standardized.
> >>
> >> >>
> >> >>
> >> >> Regards,
> >> >>
> >> >> ~ Simon
> >> >>
> >> >> On Mon, Dec 8, 2008 at 4:22 AM, Gerhard Petracek
> >> >> <gerhard.petracek@gmail.com
> >>
> >> <mailto:gerhard.petracek@gmail.com>> wrote:
> >> >>
> >> >>    hello paul,
> >> >>
> >> >>    ok - let's continue with the case you mentioned.
> >>
> >> >>
> >> >>    we could:
> >> >>     - use the same approach of the myfaces shared module also for the
> >> >>    shared
> >>  skinning code
> >> >>     - provide skinning as an independent jar file (it's easier for
> >> >>    other projects/custom components to re-use it)
> >> >>
> >> >>    regards,
> >> >>    gerhard
> >>
> >> >>
> >> >>
> >> >>
> >> >>    2008/12/8 Paul Rivera <paul_mrivera@yahoo.com
> >> >>    <mailto:paul_mrivera@yahoo.com>>
> >>
> >> >>
> >> >>        Hi,
> >> >>
> >> >>        It's good to hear that there's effort done to make
> >> skinning
> >> >>        standardized and part of JSF by Simon.  Is there anything that
> >> >>        the current skinning project we have at
> >>
> >> >>        http://code.google.com/p/myfaces-csi/ can contribute to this?
> >> >>
> >> >>        In the event that Simon's ideas don't get integrated
> >>
> >> into JSF
> >> >>        2.0, I'd like to bring back the discussion to the skinning
> >> >>        project that we now have in the link mentioned
> >>  above.
> >> >>
> >> >>        Overall, I think the community agrees with the idea of having
> >> >>        an independent skinning project that is basically derived from
> >> >>        trinidad code.  I'd like to hear your opinion on the
> >>
> >> project
> >> >>        layout described in
> >> >>
> http://code.google.com/p/myfaces-csi/wiki/MyfacesSkinsProposal.
> >>
> >> >>
> >> >>        What concerns me most here is that the skins project and
> >> >>        trinidad share a lot of classes that it is hard to get a clean
> >> >>        separation.  You can check shared-impl for those classes.
> >>
> >> >>
> >> >>        Our current layout has a shared module (shared-api,
> >> >>        shared-impl).  This module contains code shared by both
> >> >>        skinning and trinidad-core.  We can probably move some of the
> >>
> >> >>        utility classes into myfaces-commons-utils.  But other classes
> >> >>
> >>        there might not be such a good fit into myfaces-commons-utils.
> >> >>
> >> >>        We started this project with the most immediate goal of giving
> >> >>        tomahawk skinning support and eventually have trinidad use
> >>
> >> >>        this project.  We've taken trinidad skinning code and now
> >> it
> >> >>        works with tomahawk and trinidad-core.  In the event that this
> >> >>        project gets accepted into myfaces, integration with tomahawk
> >>
> >> >>        is not a big problem.  I am actually more worried with the
> >> >>        changes we have to make in trinidad-core.  This is why I'd
> >> >>        like to propose as a roadmap:
> >> >>          - finish the skinning project and make the necessary changes
> >>
> >> >>        in trinidad-core without adding new features yet to the
> >> >>        current set that trinidad has.  There will be big changes in
> >> >>        trinidad-core that
> >>  need to be done at the same time.
> >> >>          - once we verify that everything is working, we can then add
> >> >>        the desired new features/changes to the skinning api.  In this
> >> >>        phase, we can implement the new features/changes to the api in
> >>
> >> >>        small and more manageable increments.
> >> >>
> >> >>        While Simon is in the process of submitting his proposal,
> >> I'd
> >> >>        like to work on these issues and anything else you think might
> >>
> >> >>        be a problem for the skinning project or the transition with
> >> >>        trinidad.
> >> >>
> >> >>        Best Regards,
> >> >>        Paul Rivera
> >> >>
> >> >>
> >> >>        --- On *Sat, 12/6/08, Gerhard Petracek
> >>
> >> >>        /<gerhard.petracek@gmail.com
> >> >>        <mailto:gerhard.petracek@gmail.com>>/* wrote:
> >>
> >> >>
> >> >>            From: Gerhard Petracek
> >>  <gerhard.petracek@gmail.com
> >> >>            <mailto:gerhard.petracek@gmail.com>>
> >>
> >> >>            Subject: Re: [Skinning] Independent skinning myfaces
> >> >>            subproject
> >> >>            To: "MyFaces Development"
> >> <dev@myfaces.apache.org
> >>
> >> >>            <mailto:dev@myfaces.apache.org>>
> >> >>            Date: Saturday, December 6, 2008, 12:42 PM
> >> >>
> >> >>
> >> >>            hello simon,
> >>
> >> >>
> >> >>            no it's just because of ie version < 7 like it is
> >> >>            mentioned in the trinidad skinning documentation.
> >> >>
> >> >>            regards,
> >> >>            gerhard
> >>
> >> >>
> >> >>
> >> >>
> >> >>            2008/12/6 Simon Lessard <simon.lessard.3@gmail.com
> >> >>            <mailto:simon.lessard.3@gmail.com>>
> >>
> >> >>
> >> >>                Hi
> >>  Gerhard,
> >> >>
> >> >>                Trinidad already has this and it would be the same
> >> >>                with what I propose. Assume: <tr:tree
> >> >>                styleClass="MyClass"/>
> >>
> >> >>
> >> >>                Then switch the selectors to: tr|tree.MyClass
> >> >>
> >> >>                As far as I can tell this is enough to cover every
> >> >>                possibilities without burdening the framework with an
> >>
> >> >>                extra attribute. Unless you can come up with a counter
> >> >>                example not involving IE6's shitty CSS support.
> >> >>
> >> >>
> >> >>                ~ Simon
> >> >>
> >>
> >> >>
> >> >>                On Sat, Dec 6, 2008 at 2:19 PM, Gerhard Petracek
> >> >>                <gerhard.petracek@gmail.com
> >> >>                <mailto:gerhard.petracek@gmail.com>> wrote:
> >>
> >> >>
> >> >>
> >>       hello simon,
> >> >>
> >> >>                    in my opinion andrew brought up an interesting
> >> >>                    question. have you also thought about multiple
> >> >>                    selectors for the same component?
> >>
> >> >>
> >> >>                    i repeat the example i mentioned before:
> >> >>
> >> >>
> >> >>                    <tr:tree/> ... uses default selector
> >> >>                    <tr:tree selectorId="myId"/> ...
> >>
> >> uses selector
> >> >>                    with "myId" to use a different selector
> >> >>
> >> >>                    regards,
> >> >>                    gerhard
> >> >>
> >> >>
> >> >>
> >>
> >> >>                    2008/12/6 Simon Lessard
> >> <simon.lessard.3@gmail.com
> >> >>                    <mailto:simon.lessard.3@gmail.com>>
> >>
> >> >>
> >> >>                        Hi all,
> >> >>
> >> >>
> >>                  Since I completed the proposition by memory
> >> >>                        yesterday I forgot some important parts. Also,
> >> >>                        I thought more about some possibilities I
> >>
> >> >>                        rejected during the night and reconsidered my
> >> >>                        those. So here is v2. Among other thing I
> >> >>                        integrated skin extends, removed selector
> >>
> >> >>                        redirection, removed some other PENDING and
> >> >>                        simplified 3.1 suggestion since I discarded
> >> >>                        redirection:
> >> >>
> >> >>                        *Modified classes*
> >>
> >> >>
> >> >>                        public abstract class Application
> >> >>                        {
> >> >>                            public String getDefaultSkinFamily();
> >> >>                            public
> >>  void setDefaultSkinFamily(String
> >> >>                        skinFamily);
> >> >>                        }
> >> >>
> >> >>                        public final class FactoryFinder
> >> >>                        {
> >>
> >> >>                            public static final String SKIN_FACTORY;
> >> >>                        }
> >> >>
> >> >>                        public class UIViewRoot
> >> >>                        {
> >>
> >> >>                            public String getSkinFamily();
> >> >>                            public void setSkinFamily(String
> >> skinFamily);
> >> >>                        }
> >> >>
> >> >>
> >> >>                        *Modified methods*
> >>
> >> >>
> >> >>                        public abstract class ViewHandler
> >> >>                        {
> >> >>                            /**
> >> >>                             * Same as before but also copy
> >>  skin
> >> family.
> >> >>                             */
> >> >>                            public abstract UIViewRoot
> >> >>                        createView(FacesContext context, String
> >> viewId);
> >> >>                        }
> >>
> >> >>
> >> >>
> >> >>                        *New classes*
> >> >>
> >> >>                        public abstract class Icon extends Resource
> >> >>                        {
> >> >>                            /**
> >>
> >> >>                             * Gets the key within the skin's
> >> >>                        ResourceBundle to the description of this
> >> >>                        icon. The description can be used
> >>
> >> >>                             * as an alternate text for the icon to
> >> >>                        improve accessibility for example.
> >> >>                             */
> >> >>                            public abstract String
> >>  getDescriptionKey();
> >> >>                                                      /**
> >> >>                             * Gets the name of this icon.
> >> >>                             */
> >> >>                            public abstract String getName();
> >>
> >> >>
> >> >>                            /**
> >> >>                             * Gets the effective style class of this
> >> >>                        icon within the skin.
> >> >>                             */
> >>
> >> >>                            public abstract String getStyleClass();
> >> >>                        }
> >> >>
> >> >>                        public abstract class Skin
> >> >>                        {
> >>
> >> >>                            public abstract Resource
> >> >>                        getContentResource(FacesContext context);
> >> >>
> >> >>                            public abstract Icon
> >>  getIcon(FacesContext
> >> >>                        context, String iconName);
> >> >>
> >> >>                            public abstract Object
> >> >>                        getProperty(FacesContext context, String
> >>
> >> >>                        propertyName);
> >> >>
> >> >>                            /**
> >> >>                             * Get the ResourceBundle for this skin in
> >> >>                        the current locale.
> >>
> >> >>                             */
> >> >>                            public abstract ResourceBundle
> >> >>                        getResourceBundle(FacesContext context);
> >> >>
> >> >>                            public abstract SkinNode
> >>
> >> >>                        getSkinNode(FacesContext context, SkinSelector
> >> >>                        selector);
> >> >>
> >> >>                            public String
> >>  getStyleClass(FacesContext
> >> >>                        context, SkinSelector selector)
> >> >>                            {
> >> >>                                SkinNode node = getSkinNode(context,
> >> >>                        selector);
> >>
> >> >>                                return node == null ? null :
> >> >>                        node.getStyleClass();
> >> >>                            }
> >> >>                        }
> >> >>
> >> >>                        public class SkinException extends
> >>
> >> FacesException
> >> >>                        {
> >> >>                            // Provides all 4 common Exception
> >> >>                        constructors
> >> >>                        }
> >> >>
> >>
> >> >>                        public abstract class SkinFactory implements
> >> >>                        FacesWrapper<SkinFactory>
> >> >>
> >>  {
> >> >>                            public abstract void addSkin(String
> >> >>                        skinFamily, String renderKitId, Skin skin);
> >> >>                            public abstract Skin getSkin(String
> >>
> >> >>                        skinFamily, String renderKitId);
> >> >>                            public abstract Collection<String>
> >> >>                        getSkinFamilies();
> >> >>                            public SkinFactory getWrapped()
> >>
> >> >>                            {
> >> >>                                return null;
> >> >>                            }
> >> >>                        }
> >> >>
> >> >>                        public class SkinInitializationException
> >>
> >> >>                        extends SkinException
> >> >>                        {
> >> >>                            // Provides all 4 common Exception
> >> >>
> >>    constructors
> >> >>                        }
> >> >>
> >> >>                        /**
> >> >>                         * Implementations of this interface are in
> >> >>                        charge of creating Skin instances in an
> >>
> >> >>                        implementation specific manner.
> >> >>                         */
> >> >>                        public interface SkinLoader
> >> >>                        {
> >> >>                            /**
> >>
> >> >>                             * Creates a new
> >> <code>Skin</code>
> >> >>                        instance the specified skinFamily and
> >> >>                        parameters. There's no garanteed as of what
> >>
> >> >>                             * parameters will be present in the Map
> >> >>                        argument and the creation should fails if
> >> >>                        those parameters are not
> >>  correct
> >> >>                             * for the specific implementation.
> >> >>                             *
> >> >>                             * @throws SkinInitializationException if
> >> >>                        the provided parameters are not sufficient to
> >>
> >> >>                        create the new <code>Skin</code>
> >> >>                             *         instance
> >> >>                             */
> >> >>                            public Skin loadSkin(Skin parentSkin,
> >>
> >> >>                        String resourceBundle, Map<String,
> >> String>
> >> >>                        parameters);
> >> >>                        }
> >> >>
> >> >>                        public abstract class SkinNode
> >>
> >> >>                        {
> >> >>                            public abstract String getStyleClass();
> >> >>
> >> >>
> >>  public abstract Map<String, Object>
> >> >>                        getProperties();
> >> >>
> >> >>                            /**
> >> >>                             * Gets a server side property of this
> >>
> >> >>                        node. Server side properties are not visible
> >> >>                        by the client.
> >> >>                             */
> >> >>                            public Object getProperty(String
> >>
> >> propertyName)
> >> >>                            {
> >> >>                                return
> >> getProperties().get(propertyName);
> >> >>                            }
> >> >>
> >> >>                            /**
> >>
> >> >>                             * Gets a read-only version of the
> >> >>                        client-side properties of this node. In HTML,
> >> >>                        those represent CSS properties.
> >>
> >> >>
> >>          *
> >> >>                             * It's valid to place those properties
> >> in
> >> >>                        a SoftRenderece for memory footprint safety.
> >> >>                        However, this
> >>
> >> >>                             * method must be able to reload them if
> >> >>                        needed
> >> >>                             * those properties should be placed in
> >> >>                        memory-aware renference
> >>
> >> >>                             */
> >> >>                            public abstract Map<String, Object>
> >> >>                        getStyleProperties();
> >> >>
> >> >>                            public Object getStyleProperty(String
> >>
> >> >>                        propertyName)
> >> >>                            {
> >> >>                                return
> >> >>
> >>  getStyleProperties().get(propertyName);
> >> >>                            }
> >> >>                        }
> >> >>
> >> >>                        public class SkinSelector implements
> >> >>                        Comparable<SkinSelector>
> >>
> >> >>                        {
> >> >>                            /**
> >> >>                             * Finds the SkinSelector with the
> >> >>                        specified name or return
> >> <code>null</code> if
> >>
> >> >>                        it doesn't exists. This
> >> >>                             * method should be called by Renderers
> >> >>                        during their initialization in order to cache
> >>
> >> >>                        the SkinSelector instances
> >> >>                             * they'll be using to increase overall
> >> >>                        performance of the Skin module.
> >> >>
> >>                   */
> >> >>                            public static SkinSelector
> >> >>                        getInstance(String selectorName);
> >> >>
> >> >>                            /**
> >> >>                             * Finds the SkinSelector with the
> >>
> >> >>                        specified name or create a new one if it
> >> >>                        doesn't exists and
> >> <code>create</code>
> >> >>                             * argument is
> >>
> >> <code>true</code>. This
> >> >>                        method should be used mainly by SkinLoader in
> >> >>                        order to register a new
> >> >>                             * selector.
> >>
> >> >>                             */
> >> >>                            public static SkinSelector
> >> >>                        getInstance(String selectorName, boolean
> >> create);
> >> >>
> >> >>
> >>                private static int nextOrdinal = 0;
> >> >>
> >> >>                            private int ordinal;
> >> >>                            private String name;
> >> >>                                                      private
> >>
> >> >> SkinSelector(String name)
> >> >>                            {
> >> >>                                assert name != null;
> >> >>
> >> synchronized
> >>
> >> >> (SkinSelector.class)
> >> >>                                {
> >> >>                                    ordinal = nextOrdinal++;
> >> >>                                }
> >> >>
> >> >>                                this.name <http://this.name> =
> >>
> >> name;
> >> >>                            }
> >> >>
> >> >>                            public boolean equals(Object obj)
> >> >>                            {
> >> >>
> >>                           // Sufficient because ordinal is unique
> >> >>                                return o == this;
> >> >>                            }
> >> >>                                                      public int
> >>
> >> hashCode()
> >> >>                            {
> >> >>                                return ordinal();
> >> >>                            }
> >> >>
> >> >>                            public String name()
> >>
> >> >>                            {
> >> >>                                return name;
> >> >>                            }
> >> >>
> >> >>                            public int ordinal()
> >> >>                            {
> >>
> >> >>                                return ordinal;
> >> >>                            }
> >> >>                        }
> >> >>
> >> >>                        *New config
> >> >>                        *
> >>
> >> >>
> >>                         <application>
> >> >>                          <default-skin-family/>
> >> >>                        </application>
> >> >>                        <skin>
> >> >>                          <skin-family/>
> >>
> >> >>                          <render-kit-id/>
> >> >>                          <description/>
> >> >>                          <extends>
> >> >>                            <skin-family/>
> >>
> >> >>                            <render-kit-id/>
> >> >>                          </extends>
> >> >>                          <skin-loader-class/>
> >> >>                          <resource-bundle/>
> >>
> >> >>                          <skin-loader-parameters>
> >> >>                            <map-entries/>
> >> >>                          </skin-loader-parameters>
> >> >>
> >>          </skin>
> >> >>                        *
> >> >>                        *
> >> >>                        PENDING: Should it instead be a
> >> >>                        getTranslatedResource instead of
> >>
> >> >>                        getResourceBundle within the Skin class?
> >> >>
> >> >>                        PENDING: Should the skin family and render kit
> >> >>                        id passed to the loader or is that irrelevant?
> >>
> >> >>
> >> >>                        PENDING: With the proposed API, Trinidad
> >> >>                        aliases wouldn't be able to be used across
> >> >>                        skin additions as it would be aggregated in a
> >>
> >> >>                        CompositeSkin instance and thus in multiple
> >> >>                        different documents, anyone has a better idea
> >> >>                        than CompositeSkin for this? Maybe
> >>  stardadize
> >> >>                        aliases somehow and have CompositeSkin
> >> >>                        aggregate the content in a single document
> >> >>                        instead of delegating to its fragments?
> >>
> >> >>
> >> >>                        PENDING: Should Skin.getIcon uses an optimized
> >> >>                        key as well? Doesn't seem required since
> >> there
> >> >>                        are much less icons in a page than HTML
> >>
> >> >>                        elements, thus the gain wouldn't worth the
> >> >>                        trouble imho.
> >> >>
> >> >>                        PENDING: The Resource API might have to be
> >>
> >> >>                        revisited in order to recognize the Resource
> >> >>                        returned by Skin.getContentResource so that
> >> >>                        ResourceHandler can identify Resource requests
> >>
> >> >>
> >>                   for the skin content and thus locate the given
> >> >>                        skin, get its Resource insteance and return
> >> >>                        the content with the standard algorithm. I
> >>
> >> >>                        believe a reserved library name could be used
> >> >>                        for that, the resource name is an harder issue
> >> >>                        though since the skin identifier is a tuple
> >>
> >> >>                        atm and defining a reserved separator
> >> >>                        character would bring limitation to the render
> >> >>                        kit ids and skin family values. Someone could
> >>
> >> >>                        come up with a better suggestion for that
> >> maybe?
> >> >>
> >> >>                        PENDING: Skin.getStyleProperties could maybe
> >> >>                        offer the option to return a mutable Map as
> >>  an
> >> >>                        optional feature, but then would requires the
> >> >>                        Skin to
> >> >>                        regenerate the style document (CSS). However
> >> >>                        this can get hellish with composite skin. The
> >>
> >> >>                        node would need to have access to its
> >> >>                        container Skin and there should be a
> >> >>                        SkinModificationEvent/Listener capability
> >>
> >> >>                        added to the Skin class.
> >> >>
> >> >>
> >> >>                        Regards,
> >> >>
> >> >>                        ~ Simon
> >> >>
> >> >>
> >> >>                        On Fri, Dec 5, 2008 at 1:21 PM, Simon Lessard
> >>
> >> >>                        <simon.lessard.3@gmail.com
> >> >>
> >>  <mailto:simon.lessard.3@gmail.com>>
> >> wrote:
> >> >>
> >> >>                            I agree with most of these statements, but
> >> >>                            I would start even higher than that, like
> >>
> >> >>                            defining the base interfaces and access
> >> >>                            classes.
> >> >>
> >> >>                            For instance, I think it's safe to
> >> assume
> >>
> >> >>                            that a Skin class or interface should
> >> >>                            exists. Let assume all interfaces for now
> >> >>                            as it takes less characters. Now, from
> >>
> >> >>                            where and how should the Skin be available
> >> >>                            for a given FacesContext. Personally I
> >> >>                            believe a Skin should be linked to a
> >>
> >> >>
> >>  RenderKit (or a common base RenderKit
> >> >>                            class for all MyFaces extensions if not in
> >> >>                            the standard), but let assume work on the
> >> >>                            API for now for the sake of the
> discussion.
> >>
> >> >>
> >> >>                            So for now we have:
> >> >>
> >> >>                            public interface Skin
> >> >>                            {
> >> >>                                public String getResourceBundle();
> >>
> >> >>                            }
> >> >>
> >> >>                            public abstract class RenderKit
> >> >>                            {
> >> >>                                public abstract Skin
> >>
> >> >>                            getSkin(FacesContext context);
> >> >>                            }
> >> >>
> >> >>                            So far so good, but now that
> >>  opens some
> >> >>                            issues that will themselves explode into
> >> more:
> >> >>
> >> >>                               1. Should the way the RenderKit locates
> >> >>                                  the current Skin standardized?
> >>
> >> >>                               2. How do we define the contract
> >> >>                                  ensuring that the Skin get rendered
> >> >>                                  on the page?
> >> >>                               3. What other functionalities should be
> >>
> >> >>                                  standarized in the Skin interface?
> >> >>
> >> >>                            *Issue 1: Current skin localization*
> >> >>                            Personally I chose yes to that question
> >>
> >> >>                            since it allow a standardized way to
> >> >>                            define skins. Let use
> >>  Trinidad's
> >> >>                            skin-family notion here, but with the way
> >> >>                            renderKitId is defined, that's the view
> >> >>                            root and a factory implementing decorator
> >>
> >> >>                            pattern. So we add
> >> >>
> >> >>                            public class UIViewRoot
> >> >>                            {
> >> >>                                public String getSkinFamily();
> >>
> >> >>                                public void setSkinFamily(String
> >> >>                            skinFamily);
> >> >>                            }
> >> >>
> >> >>                            public abstract class SkinFactory
> >>
> >> >>                            implements FacesWrapper<SkinFactory>
> >> >>                            {
> >> >>                                public abstract void addSkin(String
> >> >>
> >>                             skinFamily, String renderKitId, Skin skin);
> >> >>                                public abstract Skin getSkin(String
> >> >>                            skinFamily, String renderKitId);
> >>
> >> >>                                public abstract
> >> Collection<String>
> >> >>                            getSkinFamilies();
> >> >>                                public SkinFactory getWrapped()
> >> >>                                {
> >>
> >> >>                                    return null;
> >> >>                                }
> >> >>                            }
> >> >>
> >> >>                            *Sub-issue 1.1: Default SkinFactory
> >>
> >> >>                            implementation behavior*
> >> >>                            Additional Exceptions
> >> >>                            public class SkinException extends
> >> >>
> >>  FacesException
> >> >>                            {
> >> >>                                // Provides all 4 common Exception
> >> >>                            constructors
> >> >>                            }
> >>
> >> >>
> >> >>                            public class SkinInitializationException
> >> >>                            extends SkinException
> >> >>                            {
> >> >>                                // Provides all 4 common Exception
> >>
> >> >>                            constructors
> >> >>                            }
> >> >>
> >> >>                            Additional interface
> >> >>                            /**
> >> >>                             * Implementations of this interface are
> >>
> >> >>                            in charge of creating Skin instances in an
> >> >>                            implementation specific manner.
> >> >>
> >>              */
> >> >>                            public interface SkinLoader
> >> >>                            {
> >> >>                                /**
> >> >>                                 * Creates a new
> >>
> >> <code>Skin</code>
> >> >>                            instance the specified skinFamily and
> >> >>                            parameters. There's no garanteed as of
> >> what
> >> >>                                 * parameters will be present in the
> >>
> >> >>                            Map argument and the creation should fails
> >> >>                            if those parameters are not correct
> >> >>                                 * for the specific implementation.
> >>
> >> >>                                 *
> >> >>                                 * @throws SkinInitializationException
> >> >>                            if the provided parameter are not enough
> >> >>
> >>                       to create the <code>Skin</code>
> >> instance
> >> >>                                 */
> >> >>                                public Skin loadSkin(String
> >> >>                            skinFamily, String resourceBundle,
> >>
> >> >>                            Map<String, String> parameters);
> >> >>                            }
> >> >>
> >> >>                            Addition to faces-config.xml:
> >> >>                            <application>
> >>
> >> >>                              <default-skin-family/>
> >> >>                            </application>
> >> >>                            <skin>
> >> >>                              <skin-family/>
> >>
> >> >>                              <render-kit-id/>
> >> >>                              <description/>
> >> >>
> >>  <skin-loader-class/>
> >> >>                              <resource-bundle/>
> >> >>                              <skin-loader-parameters>
> >> >>                                <map-entries/>
> >>
> >> >>                              </skin-loader-parameters>
> >> >>                            </skin>
> >> >>
> >> >>                            Note that this solution makes
> >> >>                            RenderKit.getSkin more an utility method
> >>
> >> >>                            than anything, except if an extension
> >> >>                            decides to override it (would probably be
> >> >>                            the casew ith Trinidad, at least to start
> >>
> >> >>                            to use trinidad-config.xml, or later to
> >> >>                            add .pda or .desktop to the current
> >> >>
> >>  skinFamily).
> >> >>
> >> >>                            Also, the framework should probably
> >> >>                            provide some implementations of SkinLoader
> >> >>                            out-of-the-box, most likely
> >>
> >> >>                            ClassSkinLoader expecting a skinClass
> >> >>                            parameter and a CSSSkinLoader receiving a
> >> >>                            cssResourcePath parameter. (Trinidad would
> >>
> >> >>                            mostl ikely provide an XSSSkinLoader for
> >> >>                            example)
> >> >>
> >> >>                            *Issue 2: Skin content rendering*
> >> >>                            How should rendering be handled? Should it
> >>
> >> >>                            be handled as an added ResourceDependency
> >> >>                            just before rendering or as an additional
> >> >>
> >>                   contract for the default HtmlRenderer for
> >> >>                            HtmlHead? The latter sounds better, but
> >> >>                            how should it be implemented? target would
> >>
> >> >>                            obviously be "head", but then a
> >> public
> >> >>                            Resource Skin.getContentResource() method
> >> >>                            could be required and this might imply
> >>
> >> >>                            some changes to the ResourceHandler
> >> >>                            specification so that it can locate the
> >> >>                            Skin instance in order to be able to serve
> >>
> >> >>                            the Resource's content (effective CSS
> >> >>                            content) to the agent. I like the Resource
> >> >>                            version, but I have more thinking to do
> >>
> >> >>
> >>       about how to implement this, maybe
> >> >>                            involving a reserved resourceIdentifier
> >> >>                            structure/syntax
> >> >>
> >> >>                            *Issue 3: Skin features*
> >>
> >> >>                            Additional class
> >> >>                            public abstract class Icon extends
> Resource
> >> >>                            {
> >> >>                                /**
> >>
> >> >>                                 * Gets the key within the skin's
> >> >>                            ResourceBundle to the description of this
> >> >>                            icon. The description can be used
> >>
> >> >>                                 * as an alternate text for the icon
> >> >>                            to improve accessibility for example.
> >> >>                                 */
> >> >>                                public
> >>  abstract String
> >> >>                            getDescriptionKey();
> >> >>                                                              /**
> >> >>                                 * Gets the name of this icon.
> >>
> >> >>                                 */
> >> >>                                public abstract String getName();
> >> >>
> >> >>                                /**
> >> >>                                 * Gets the effective style class of
> >>
> >> >>                            this icon within the skin.
> >> >>                                 */
> >> >>                                public abstract String
> getStyleClass();
> >> >>                            }
> >>
> >> >>
> >> >>                            public interface Skin
> >> >>                            {
> >> >>                                public Icon getIcon(String iconName);
> >> >>
> >> >>
> >>           public String getProperty(String
> >> >>                            propertyKey);
> >> >>
> >> >>                                public String getResourceBundle();
> >> >>
> >> >>                                public String getStyleClass(String
> >>
> >> >>                            selectorKey);
> >> >>                            }
> >> >>
> >> >>                            *Sub-issue 3.1: style class / property /
> >> >>                            icon access strategy*
> >>
> >> >>                            Trinidad uses String keys to access style
> >> >>                            classes within the skin. That strategy is
> >> >>                            very flexible, but alas very slow, thanks
> >>
> >> >>                            to String.hashCode() being linear and
> >> >>                            uncached. So, even if String.intern() is
> >> >>                            called
> >>  on all selectors within a given
> >> >>                            skin, the gain will only be on
> >> >>                            String.equals, making it O(1) instead of
> >> >>                            O(n). Even if this is better than nothing,
> >>
> >> >>                            especially it there's a collision, the
> >> >>                            overall complexity of looking up a
> >> >>                            selector remains O(n) with the length of
> >>
> >> >>                            the key. So, the overall cost of skinning
> >> >>                            with this strategy is averageLengthOfKey *
> >> >>                            averageAmountOfComponentPerPage *
> >>
> >> >>                            averageAmountOfHtmlElementPerComponent
> >> >>                            (assuming each element gets its own style
> >> >>                            class which is required for
> >>  maximum
> >> >>                            customizability). Another, but a little
> >> >>                            bit more complex, solution is also
> >> >>                            possible using a "dynamic enum"
> >>
> >> alike to
> >> >>                            PropertyKey in Trinidad. So I'd like
> >> >>                            something like:
> >> >>
> >> >>                            public abstract class SkinKeyPart
> >>
> >> >>                            {
> >> >>                                public String name();
> >> >>
> >> >>                                public int ordinal();
> >> >>                            }
> >>
> >> >>
> >> >>                            public class Namespace extends SkinKeyPart
> >> >>                            {
> >> >>                                /**
> >> >>                                 * Find or create the Namespace
> >>
> >> >>
> >>              instance with the specified name.
> >> >>                                 */
> >> >>                                public static Namespace
> >> >>                            getInstance(String name);
> >>
> >> >>                            }
> >> >>
> >> >>                            public class ComponentKey extends
> >> SkinKeyPart
> >> >>                            {
> >> >>                                /**
> >>
> >> >>                                 * Find or create the ComponentKey
> >> >>                            instance with the specified name.
> >> >>                                 */
> >> >>                                public static ComponentKey
> >>
> >> >>                            getInstance(String name);
> >> >>                            }
> >> >>
> >> >>                            public class ComponentPartKey extends
> >> >>
> >>  SkinKeyPart
> >> >>                            {
> >> >>                                /**
> >> >>                                 * Find or create the ComponentPartKey
> >> >>                            instance with the specified name.
> >>
> >> >>                                 */
> >> >>                                public static ComponentPartKey
> >> >>                            getInstance(String name);
> >> >>                            }
> >>
> >> >>
> >> >>                            public class ComponentStateKey extends
> >> >>                            SkinKeyPart
> >> >>                            {
> >> >>                                /**
> >>
> >> >>                                 * Find or create the
> >> >>                            ComponentStateKey instance with the
> >> >>                            specified name.
> >> >>                                 */
> >>
> >> >>
> >>                              public static ComponentPartKey
> >> >>                            getInstance(String name);
> >> >>                            }
> >> >>
> >> >>                            public abstract class SkinNode
> >>
> >> >>                            {
> >> >>                                public abstract String[]
> >> >>                            getStyleClasses();
> >> >>                                public abstract String
> >>
> >> >>                            getProperty(String propertyName);
> >> >>                                public abstract Icon getIcon(String
> >> >>                            iconName);
> >> >>                                public abstract SkinNode
> >>
> >> >>                            getSubPart(ComponentPartKey partKey);
> >> >>                            }
> >> >>
> >> >>                            public interface Skin
> >> >>
> >>              {
> >> >>                                /**
> >> >>                                 * Still exists to get properties
> >> >>                            global to the whole skin if someone ever
> >>
> >> >>                            need that feature
> >> >>                                 */
> >> >>                                public String getProperty(String
> >> >>                            propertyName);
> >>
> >> >>
> >> >>                                /**
> >> >>                                 * No change here
> >> >>                                 */
> >> >>                                public String getResourceBundle();
> >>
> >> >>
> >> >>                                public String getSkinNode(Namespace
> >> >>                            ns, ComponentKey component);
> >> >>
> >> >>                                public String getSkinNode(Namespace
> >>
> >> >>
> >>                    ns, ComponentKey component,
> >> >>                            ComponentStateKey state);
> >> >>
> >> >>                                public String getSkinNode(Namespace
> >> >>                            ns, ComponentKey component,
> >>
> >> >>                            ComponentStateKey... states);
> >> >>                            }
> >> >>
> >> >>                            That solution has the advantage of being
> >> >>                            very fast, actually a real O(1) for every
> >>
> >> >>                            node access assuming the Renderer gathers
> >> >>                            the keys it needs during instanciation.
> >> >>                            Then the "root" SkinNode could
> >>
> >> probably be
> >> >>                            located using a base Renderer class and
> >> >>                            passed to a custom encoding method
> >> >>
> >>                       (Trinidad's encodeAll for example). Of
> >> >>                            course, the skin loaders would have to
> >> >>                            create skin instances structuring the
> >>
> >> >>                            selectors accordingly. A base class for
> >> >>                            Skin with such feature should probably be
> >> >>                            provided if this solution is wanted in
> >>
> >> >>                            order to make new implementation of Skin
> >> >>                            easier to create.
> >> >>
> >> >>                            *PENDIND issues:*
> >> >>                            PENDING: Should the path leverage the
> >>
> >> >>                            Resource API instead and receive a
> >> >>                            library-name, library-version,
> >> >>                            resource-name and resource-version
> >>  instead?
> >> >>
> >> >>                            PENDING: A CompositeSkin class should
> >> >>                            probably be provided and most likely
> >> >>                            usable from the configuration, should it
> >>
> >> >>                            be using a specific loader with parameters
> >> >>                            or have a fully-fledged tag like
> >> >>                            <composite-skin> for example? The use
> >>
> >> of
> >> >>                            such skin implementation would be for
> >> >>                            users using multiple libraries, each with
> >> >>                            very different RenderKit implementations.
> >>
> >> >>                            A composite RenderKit class could also be
> >> >>                            useful here.
> >> >>
> >> >>                            PENDING: Should Trinidad's
> >>  SkinAddition
> >> >>                            notion be considered? SkinAddition
> >> >>                            provides a way to add skin elements to an
> >> >>                            existing skin based on its id. It would be
> >>
> >> >>                            possible to leverage that by using the
> >> >>                            skin-family/render-kit-id tuple instead.
> >> >>                            Another option would be to simply have the
> >>
> >> >>                            default SkinFactory implementation to
> >> >>                            automatically agreggate the Skin instances
> >> >>                            with the same skin-family and
> >>
> >> >>                            render-kit-id into a CompositeSkin
> >> instance.
> >> >>
> >> >>                            PENDING: Should additional metadata be
> >> >>                            added to <renderer> tag to
> >>  define the
> >> >>                            supported skin selector for tooling
> >> >>                            purpose? This point is dependant on the
> >> >>                            content of the Skin interface and the
> >>
> >> >>                            strategy chosen to access the
> >> >>                            properties/style class of a given
> >> >>                            component and/or one of its sub-element.
> >>
> >> >>
> >> >>                            PENDING: Should the effective CSS
> >> >>                            properties stay accessible in memory or
> >> >>                            otherwise from the Skin instance? If so,
> >>
> >> >>                            should they be modifiable? I tend toward
> >> >>                            no for both for performance issues. Of
> >> >>                            course this could be also left as an
> >>
> >> >>
> >>               optional operation of the interface,
> >> >>                            throwing UnsupportedOperationException in
> >> >>                            most case but at least leaving the
> >> >>                            possibility for special implementations
> >>
> >> >>                            requiring it. This point also impact issue
> >> >>                            2 in some ways.
> >> >>
> >> >>                            PENDING: About Icon, it should probably
> >>
> >> >>                            also leverage the Resource API, how should
> >> >>                            that be implemented?
> >> >>
> >> >>                            PENDING: Icon's styleClass, should the
> >>
> >> >>                            instance directly return an effective
> >> >>                            class or should it rather return a
> >> >>                            selector that would then be
> >>  looked up from
> >> >>                            the Skin? I prefer the latter, but then
> >> >>                            there's the Stirng issue so maybe the
> >> icon
> >> >>                            would have to return an optimized selector
> >>
> >> >>                            key as mentioned in 3.1
> >> >>
> >> >>                            PENDING: Solution to issue 3.1, although
> >> >>                            very fast and flexible, can be an linkage
> >>
> >> >>                            nightmare. For example, a node for
> >> >>                            component "inputText" with states
> >> >>                            "disabled" and
> >>
> >> "required" should be able
> >> >>                            to link to the component part node for
> >> >>                            part "label" of
> >> "inputText" without any
> >> >>                            state defined if needed. The
> >>  performance
> >> >>                            gain of 3.1 is great, the implementation
> >> >>                            complexity isn't. Still, personally I
> >> >>                            don't have any problem throwing
> >>
> >> complexity
> >> >>                            at implementor's head if the users can
> >> >>                            feel the difference. Another option would
> >> >>                            be to remove the "state"
> >>
> >> complexity part
> >> >>                            and have a predefined style class syntax
> >> >>                            for those. That solution is what Trinidad
> >> >>                            does. However, this solution is not as
> >>
> >> >>                            flexible as it doesn't allow to switch
> >> >>                            Icon dynamically depending on the
> >> >>                            component's state.
> >> >>
> >>
> >> >>
> >>                             PENDING: Solution 3.1 don't allow state
> >> to
> >> >>                            be applied on the component's sub
> >> parts.
> >> >>                            Most of the time it's not an issue, but
> >>
> >> we
> >> >>                            have one such use case with Trinidad's
> >> >>                            train component where the train itself
> >> >>                            doesn't have a state, but each of its
> >>
> >> >>                            station (sub-part) can be
> >> >>                            visited/unvisited and/or selected and/or
> >> >>                            disabled. If 3.1 is kept, should it be
> >>
> >> >>                            tweaked even more to allow a sub-part
> >> >>                            state on a per part basis as well? This
> >> >>                            makes the linkage a nightma
> >>
> >> >
> >> > ...
> >> >
> >> > [Message
> >>  clipped]
> >>
> >>
> >>
> >> --
> >> Matthias Wessendorf
> >>
> >> blog: http://matthiaswessendorf.wordpress.com/
> >> sessions: http://www.slideshare.net/mwessendorf
> >>
> >> twitter: http://twitter.com/mwessendorf
> >>
> >
> >
> >
> > --
> >
> > http://www.irian.at
> >
> > Your JSF powerhouse -
> > JSF Consulting, Development and
> > Courses in English and German
> >
> > Professional Support for Apache MyFaces
> >
>
>
>
> --
> Matthias Wessendorf
>
> blog: http://matthiaswessendorf.wordpress.com/
> sessions: http://www.slideshare.net/mwessendorf
> twitter: http://twitter.com/mwessendorf
>



-- 

http://www.irian.at

Your JSF powerhouse -
JSF Consulting, Development and
Courses in English and German

Professional Support for Apache MyFaces

Mime
View raw message