admin@glassfish.java.net

Re: HK2 talk tomorrow (1/22) at 11 am PST

From: Ken Paulsen <Ken.Paulsen_at_Sun.COM>
Date: Fri, 25 Jan 2008 14:41:17 -0800

For this first release, I suspect we will mainly have a single type of
"integrationpoint" object. However, if we start using these as model
objects rather than meta-data objects, I will create different types for
them -- I do see the value in doing that.

Thanks for your feedback!

Ken


Kohsuke Kawaguchi wrote:
>
> If every integration points use the same set of properties, then you
> are right that there's not much point in defining them differently.
> Tabs and tree nodes are certainly similar enough that I agree having a
> single interface is sufficient.
>
> But I guess I was assuming that there are other extension points that
> are somewhat different --- for example, the extension point for custom
> branding, the extension point for "common tasks" list, the extension
> point for the different filtering types, etc.
>
> The other part of the reasoning for me was that I meant these
> different extension point implementations to serve as the model
> object, in which case strongly typing them has more meaning. But if
> these are only used as implementation-detail in-memory data structure
> inside admin module (and people are writing them in XML, as in your
> earlier proposals), then this doesn't matter much.
>
>
> Ken Paulsen wrote:
>>
>> I'd also like to look at this from the perspective of a consumer of
>> these "integration points." Which of these is preferable?
>>
>> #1:
>>
>> // Get integration points for the "tree"
>> List<IntegrationPoint> points = service.getIntegrationPoints("myTree");
>> for (IntegrationPoint point : points) {
>> point.getId();
>> point.priority();
>> point.getParentId();
>> point.getContent();
>> }
>> // Same api's for "tab" (and everything else):
>> points = service.getIntegrationPoints("applicationTab");
>> for (IntegrationPoint point : points) {
>> point.getId();
>> point.priority();
>> point.getParentId();
>> point.getContent();
>> }
>>
>>
>>
>> #2:
>>
>> // Get integration points for the "tree"
>> List<TreeIntegrationPoint> treePoints =
>> service.getTreeIntegrationPoints("myTree");
>> for (TreeIntegrationPoint treePoint : treePoints) {
>> treePoint.getId();
>> treePoint.priority();
>> treePoint.getParentId();
>> treePoint.getContent();
>> }
>> // Different api's for "tab" (and everything else):
>> List<TabIntegrationPoint> tabPoints =
>> service.getTabIntegrationPoints("applicationTab");
>> for (TabIntegrationPoint tabPoint : tabPoints) {
>> tabPoint.getId();
>> tabPoint.priority();
>> tabPoint.getParentId();
>> tabPoint.getContent();
>> }
>>
>>
>>
>> These two examples assume that we are describing the integration
>> point, not the content of the integration point (i.e. strategies #1
>> or #2 below). I am not clear on if "service" in the second example
>> would actually need to be 2 service objects (i.e. 1 for each new type
>> of "IntegrationPoint"). Or perhaps we can have a base
>> IntegrationPoint type and a single api which will return a List with
>> typed children. I always struggle in a situation like that to get
>> the <generics> declared correctly to avoid casting... but maybe it
>> can be done.
>>
>> Anyway here are my thoughts on advantages / disadvantages:
>>
>> Advantages for #1:
>>
>> * Concise API (one class to learn, not one for every type).
>> * Easier to write generic code to handle any type of
>> IntegrationPoint, even ones that don't exist today.
>>
>> Advantages for #2:
>>
>> * Code completion (although, if we don't have anything different
>> between IntegrationPoint types... this won't matter much).
>> * Code is easier to read
>>
>> Since the content of the IntegrationPoints is likely to be the main
>> differentiator between these objects... and in cases #1 & #2 the
>> content is opaque, I see little value in adding new class types. If
>> we go with approach #3, then the entire content of the GUI is
>> described in these objects and it would make a lot of sense to have
>> many different types. We should also keep in mind, that the
>> "integrator's" interface should typically be via the XML (or other
>> markup)... only the admin GUI team, or someone writing code to
>> consume integration points will see this API.
>>
>> Let me know your thoughts and/or what I'm missing!
>>
>> Thanks,
>>
>> Ken
>>
>>
>> Ken Paulsen wrote:
>>>
>>> As discussed in the meeting, here are some options on how a
>>> integrator could specify these integration points (in all cases I
>>> will show tab and tree examples, although other types like help,
>>> button, text, custom java code, etc need to also work).
>>>
>>> *#1) "annotate" a JSF page fragment:*
>>>
>>> id: myTab
>>> type: applicationTab
>>> priority: 22
>>> parentId: webApplicationTab
>>>
>>> <sun:tab id="general" immediate="true"
>>> text="$resource{i18n.common.General}" >
>>> <!command
>>> setSessionAttribute(key="appGeneralTabs" value="general");
>>> urlencode(value="#{name}", value=>$pageSession{name});
>>> redirect(page="#{generalPage}?appName=#{name}");
>>> />
>>> </sun:tab>
>>>
>>>
>>> id: jbiRootNode
>>> type: treeNode
>>> priority: 840
>>> parentId: rootNode
>>>
>>> <sun:treeNode id="JBIRoot"
>>> expanded="true"
>>> rendered="#{JBIHookBean.jbiJarsAvailable &&
>>> JBIConfigBean.jbiEnabled}"
>>> target="main"
>>> text="$resource{i18n.tree.jbi.root}"
>>> toolTip="$resource{i18n.tree.jbi.root.toolTip}"
>>> url="jbi/pe/root.jsf">
>>> <!facet image>
>>> <sun:iconHyperlink id="image" icon="TREE_FOLDER"
>>> url="jbi/pe/root.jsf" target="main" border="0" immediate="true"
>>> toolTip="$resource{i18n.tree.jbi.root.toolTip}" />
>>> </facet>
>>>
>>> <dynamicTreeNode id="jbiDeployments"
>>> childExpanded="false"
>>> childImageURLbase="resource/images/jbi/"
>>> childTarget="main"
>>> childURLbase="/jbi/pe/showDeployment.jsf?"
>>> expanded="false"
>>> rendered="#{JBIHookBean.jbiJarsAvailable &&
>>> JBIConfigBean.jbiEnabled}"
>>> target="main"
>>> text="$resource{i18n.tree.jbi.deployments}"
>>> toolTip="$resource{i18n.tree.jbi.deployments.toolTip}"
>>> treeAdaptorClass="com.sun.jbi.jsf.util.JBIHookTreeAdaptor"
>>> treeAdaptorListType="deployments"
>>> url="/jbi/pe/deployments.jsf">
>>> <!facet image>
>>> <sun:iconHyperlink id="saLink" icon="TREE_FOLDER"
>>> url="/jbi/pe/deployments.jsf" target="main" border="0"
>>> immediate="true" />
>>> </facet>
>>> </dynamicTreeNode>
>>>
>>>
>>>
>>> Advantages:
>>>
>>> * Cut/paste existing code (faster development from v2 -> v3)
>>> * 1 file to add an integration into GUI
>>>
>>> Disadvantages:
>>>
>>> * Exposes JSF directly as integration mechanism (harder for
>>> non-jsf integrators)
>>>
>>> Requires:
>>>
>>> * Custom "ConfigParser"
>>>
>>>
>>> *#2) Separate Configuration, still use .jsf pages/fragments:
>>> *
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <!DOCTYPE gui-config PUBLIC ...>
>>>
>>> <gui-config id="myIntegration">
>>> <tab id="myTab" type="webApplicationTab" priority="22"
>>> parentId="webApplicationTab" uri="/myTab.jsf" />
>>> <treeNode id="jbiRootNode" priority="840" parentId="rootNode"
>>> uri="/myTreeNode.jsf" />
>>> </gui-config>
>>>
>>>
>>> */myTab.jsf:*
>>> <sun:tab id="general" immediate="true"
>>> text="$resource{i18n.common.General}" >
>>> <!command
>>> setSessionAttribute(key="appGeneralTabs" value="general");
>>> urlencode(value="#{name}", value=>$pageSession{name});
>>> redirect(page="#{generalPage}?appName=#{name}");
>>> />
>>> </sun:tab>
>>>
>>>
>>> */myTreeNode.jsf:*
>>> <sun:treeNode id="JBIRoot"
>>> expanded="true"
>>> rendered="#{JBIHookBean.jbiJarsAvailable &&
>>> JBIConfigBean.jbiEnabled}"
>>> target="main"
>>> text="$resource{i18n.tree.jbi.root}"
>>> toolTip="$resource{i18n.tree.jbi.root.toolTip}"
>>> url="jbi/pe/root.jsf">
>>> <!facet image>
>>> <sun:iconHyperlink id="image" icon="TREE_FOLDER"
>>> url="jbi/pe/root.jsf" target="main" border="0" immediate="true"
>>> toolTip="$resource{i18n.tree.jbi.root.toolTip}" />
>>> </facet>
>>>
>>> <dynamicTreeNode id="jbiDeployments"
>>> childExpanded="false"
>>> childImageURLbase="resource/images/jbi/"
>>> childTarget="main"
>>> childURLbase="/jbi/pe/showDeployment.jsf?"
>>> expanded="false"
>>> rendered="#{JBIHookBean.jbiJarsAvailable &&
>>> JBIConfigBean.jbiEnabled}"
>>> target="main"
>>> text="$resource{i18n.tree.jbi.deployments}"
>>> toolTip="$resource{i18n.tree.jbi.deployments.toolTip}"
>>> treeAdaptorClass="com.sun.jbi.jsf.util.JBIHookTreeAdaptor"
>>> treeAdaptorListType="deployments"
>>> url="/jbi/pe/deployments.jsf">
>>> <!facet image>
>>> <sun:iconHyperlink id="saLink" icon="TREE_FOLDER"
>>> url="/jbi/pe/deployments.jsf" target="main" border="0"
>>> immediate="true" />
>>> </facet>
>>> </dynamicTreeNode>
>>>
>>>
>>>
>>> Advantages:
>>>
>>> * Cut/paste existing code (faster development from v2 -> v3)
>>> * Separation of configuration makes re-use easier (i.e. includes)
>>> * Content is kept out of configuration
>>> * May be able to leverage existing ConfigParser
>>>
>>> Disadvantages:
>>>
>>> * Exposes JSF directly as integration mechanism (harder for
>>> non-jsf integrators)
>>>
>>> Requires:
>>>
>>> *
>>>
>>>
>>>
>>> *#3) Abstract JSF, use "@Configured" beans for meta-data*
>>>
>>> NOTE: XML syntax of ".gui" files would need to be defined. It could
>>> be extensible via the hk2 ConfigParser. It may be able to
>>> generalize gui concepts such as tabs/trees/menus more easily and
>>> could adapt to different technologies besides JSF. Some of the JSF
>>> concepts (i.e. "immediate") may have to be removed, or be renamed to
>>> abstract them.
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> <!DOCTYPE gui-config PUBLIC ...>
>>>
>>> <gui-config id="myIntegration">
>>> <tab id="myTab" type="webApplicationTab" priority="22"
>>> parentId="webApplicationTab" uri="/myTab.gui" />
>>> <treeNode id="jbiRootNode" priority="840" parentId="rootNode"
>>> uri="/myTreeNode.gui" />
>>> </gui-config>
>>>
>>>
>>> */myTab.gui:*
>>> <tab id="general" immediate="true" text="#{i18n.common.General}" >
>>> <event type="command">
>>> setSessionAttribute(key="appGeneralTabs" value="general");
>>> urlencode(value="#{name}", value=>$pageSession{name});
>>> redirect(page="#{generalPage}?appName=#{name}");
>>> </event>
>>> </tab>
>>>
>>>
>>> */myTreeNode.jsf:*
>>> <treeNode id="JBIRoot"
>>> expanded="true"
>>> rendered="#{JBIHookBean.jbiJarsAvailable &&
>>> JBIConfigBean.jbiEnabled}"
>>> target="main"
>>> text="#{i18n.tree.jbi.root}"
>>> toolTip="#{i18n.tree.jbi.root.toolTip}"
>>> url="jbi/pe/root.jsf">
>>> <facet name="image">
>>> <iconHyperlink id="image" icon="TREE_FOLDER"
>>> url="jbi/pe/root.jsf" target="main" border="0" immediate="true"
>>> toolTip="#{i18n.tree.jbi.root.toolTip}" />
>>> </facet>
>>>
>>> <dynamicTreeNode id="jbiDeployments"
>>> childExpanded="false"
>>> childImageURLbase="resource/images/jbi/"
>>> childTarget="main"
>>> childURLbase="/jbi/pe/showDeployment.jsf?"
>>> expanded="false"
>>> rendered="#{JBIHookBean.jbiJarsAvailable &&
>>> JBIConfigBean.jbiEnabled}"
>>> target="main"
>>> text="$resource{i18n.tree.jbi.deployments}"
>>> toolTip="$resource{i18n.tree.jbi.deployments.toolTip}"
>>> treeAdaptorClass="com.sun.jbi.jsf.util.JBIHookTreeAdaptor"
>>> treeAdaptorListType="deployments"
>>> url="/jbi/pe/deployments.jsf">
>>> <facet name="image">
>>> <iconHyperlink id="saLink" icon="TREE_FOLDER"
>>> url="/jbi/pe/deployments.jsf" target="main" border="0"
>>> immediate="true" />
>>> </facet>
>>> </dynamicTreeNode>
>>>
>>>
>>>
>>> Advantages:
>>>
>>> * JSF is abstracted (easier for non-jsf developers)
>>> * Abstraction allows different UI / Themes to be rendered w/o too
>>> much difficulty
>>> * Code generation necessary will help effort to dynamically
>>> generate UI
>>> * Content is kept out of configuration
>>> * Leverage existing ConfigParser + other HK2 concepts
>>>
>>> Disadvantages:
>>>
>>> * Much slower to migrate existing GUI application from v2 -> v3
>>> * Many design details need to be solved before significant
>>> development can begin (xml format, etc)
>>> * Cannot leverage existing JSF user-base to extend admin console
>>>
>>> Requires:
>>>
>>> * Converting significant (possibly all) of current GUI application
>>>
>>>
>>> *#4) Java-based integration*
>>>
>>> I won't show examples here... but this would use @annotations in
>>> java files to define the same data as above (like @TreeNode
>>> annotations, etc.). All meta-data would need to exist in java code
>>> or annotations.
>>>
>>> Advantages:
>>>
>>> * Easy for non-gui developers
>>> * Perhaps is a basis for code-gen'd approach
>>> * May be possible to combine this approach with any of the above
>>> solutions.
>>> * JSF is abstracted (easier for non-jsf developers)
>>> * Abstraction allows different UI / Themes to be rendered w/o too
>>> much difficulty
>>> * Leverage existing @Service / @Contract annotations that
>>> developers are familiar with.
>>>
>>> Disadvantages:
>>>
>>> * Much slower to migrate existing GUI application from v2 -> v3
>>> * Unnatural to GUI developers
>>> * GUI-specific content may be needed in source code where it
>>> doesn't really belong (image names, etc)
>>> * Many design details need to be solved before significant
>>> development can begin
>>>
>>> Requires:
>>>
>>> * Would almost certainly require a combination of one of the other
>>> options to be feasible. Disadvantages mostly go away if
>>> combined with another option b/c developers have choices.
>>>
>>>
>>> I'm sure there are countless other ways to approach this, these are
>>> just the ones that come to mind right now. If anyone has other
>>> suggestions, now is the time for us to consider them. :) We need to
>>> be mindful of the amount of development time we have an the other
>>> features we'd like to implement as well.
>>>
>>> Thanks!
>>>
>>> Ken
>>>
>>>
>>> Kohsuke Kawaguchi wrote:
>>>> Nazrul Islam wrote:
>>>>> We will meet tomorrow (Tuesday, 1/22) at 11 am PST. Kohsuke will
>>>>> talk about HK2 and how it relates to administration. Slides will
>>>>> be sent out before the meeting.
>>>>
>>>> Slides attached.
>>>>
>>>>>
>>>>> Agenda
>>>>> HK2
>>>>>
>>>>> Conf Number
>>>>> Toll Free: (866) 230-6968
>>>>> Int'l Access: (865) 544-7856
>>>>> Access Code: 3846234
>>>>>
>>>>> Conf Room Peter Pan's Flight
>>>>> SCA 12 Room 3130
>>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: admin-unsubscribe_at_glassfish.dev.java.net For
>>> additional commands, e-mail: admin-help_at_glassfish.dev.java.net
>
>