On Tue, Dec 9, 2008 at 1:03 AM, Jeanne Waldman
<[EMAIL PROTECTED]> 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
>> <[EMAIL PROTECTED] <mailto:[EMAIL PROTECTED]>> 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 <[EMAIL PROTECTED]
>>    <mailto:[EMAIL PROTECTED]>>
>>
>>        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
>>        /<[EMAIL PROTECTED]
>>        <mailto:[EMAIL PROTECTED]>>/* wrote:
>>
>>            From: Gerhard Petracek <[EMAIL PROTECTED]
>>            <mailto:[EMAIL PROTECTED]>>
>>            Subject: Re: [Skinning] Independent skinning myfaces
>>            subproject
>>            To: "MyFaces Development" <[email protected]
>>            <mailto:[email protected]>>
>>            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 <[EMAIL PROTECTED]
>>            <mailto:[EMAIL PROTECTED]>>
>>
>>                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
>>                <[EMAIL PROTECTED]
>>                <mailto:[EMAIL PROTECTED]>> 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 <[EMAIL PROTECTED]
>>                    <mailto:[EMAIL PROTECTED]>>
>>
>>                        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
>>                        <[EMAIL PROTECTED]
>>                        <mailto:[EMAIL PROTECTED]>> 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

Reply via email to