Vwp next

Architectural changes for Visual Web Next

Disclaimer: This page is a living document, mainly to bring in ideas to work out possible architectural changes required in Visual Web to fit in other Web Technologies. There is no guarantee that these ideas will be implemented.

Also note that this is not a planning document for Visual Web Next. This is here mainly to analyze the short coming of current architecture and brainstorm for possible solutions

Modification History:
October 31, 2007 - Winston Prakash
October 24, 2007 - Sandip Chitale


Contents



Goal

The goal of re-architecting Visual Web Design System is to support not only JSP based JSF visual authoring, but to support other JSF View technologies such as Facelet or other Web Technologies such as PHP or Ruby.

Visual Web Design System includes

  • Source modeling and synchronization (insync module)
  • Visual Page Designer
  • Palette
  • Propertysheet
  • Navigation outline
  • Data binding support
  • Rich designtime interaction support

Web Application Technology includes

  • Web Framework such as
  • Components if available (Ex. JSF components)
  • Redering Engine (Ex. Ruby rendering Engine)
  • Hook to the Java EE platform

Unfortunately, the current Visual Web Design System was designed only to support JSP based JSF Web Application Technology. This is a limiting factor for NetBeans, because there are several users interested in using Visual Web Design System for other Web Technologies

Remove hard dependency on Java for JSP based JSF support

Currently there is a hard coded one to one dependency between JSP and Java for each Visual JSP based JSF page. The Java part is mainly used to include the proprietary "Application model" and to persist the binding information for easy resurrection of DesignBean hierarchy in the Design System. In order to remove the dependency on a Java class for each JSP page, we need to

  • Modify creation of DesignBean Hierarchy for JSP (See below)
  • Make "Application model" an optional goody.
  • Remove the hard coded JSP JSF Loader dependency on JSF Java Loader
  • If a template adds Java as an additional resource it should be made available as a resource
  • Associate JSP to Java only if user choose to use Application Model

<MD> It would be helpful to have an explanation of how the design time and runtime characteristics of the application would change depending on whether or not the appmodel was enabled. If the appmodel is disabled, what would we give up? What would we gain? (other than avoiding hard dependencies between JSP & Java)?

<WP> Personally I don't see any gain, but rather a lot to loose. But some purist think it is proprietary. However, I disagree with that. Any one who understands JSF lifecycle and ability to hook in to JSF lifecycle using decorated viewhandler will not look at it as proprietary code, but a convenient utility. Without it user need to write the whole JSF lifecycle hookup them self in order to write a complex web application.

One lame argument I heard is, the backing bean can not be extended with other technologies, because it is extended with AbstractPageBean of Application model. This argument is lame, because the backing bean is useless with out Application model and it won't participate in the JSF lifecycle at all, unless users manually hook it up with JSF lifecycle with decorated viewhandler or Lifecycle Listener. In that case they could use any Java class for that purpose.

<SVC>A middle ground could be to use an interface instead of abstract base classes from the viewhandler. Then users could extends the abstract base classes, implement the interfaces but use some other super classe (plus delegation) or not at all (i.e. the user handles the JSF lifecycle through a custom ViewHandler.).</SVC>'

Having said that for the sake of those purist, who are willing to write the lifecycle hookup themself, we could make Application Model optional i.e user could uncheck the "Use Application Model" checkbox in the page creation dialog. In that case we will not create the backing bean (if we could get rid of binding) or will not extend the backing bean with AbstractPageBean if it is used merely for binding.

Currently insync depends on one of the Application model method (init()) to inject some of the initialization code. We need to come up with some other way to initialize these values. May be as initialized managed property in the faces config file.

<SVC>Actually the designtime support for a particular component is supposed to let Insync know what is the init and destroy method for initialization of Java persisted properties and cleanup respectively. Currently it turns out to that the init() and destrouy() methods are used - consistent with the appbase application model.</SVC>

Another option, I like is what Pavel suggested (See below -- Replacing "proprietary" Application Model). Application model is nothing but a decorated viewhandler. Instead of keeping it in a jar file, simply inject the code in to the project and put the viewhandler entry in the faces-config file. That would make the purist happy as they would get a chance to modify the code as they like.

One of the thing I would really like to fix is, how the Application model ViewHandler implementation tries to find the backing bean -- via a 1:1 package correspondence (both page and backing bean must reside in the same directory hierarchy). We should come up with some other way, so that we could allow the user to place their backing bean any place they want.

Replacing "proprietary" Application Model.

The Application Model is consider proprietary because the Backing bean is extended with classes (AbstractPageBean) from the Application Model jar which has package like "com.sun.rave.web.ui.appmodel.appbase*". Because it is packaged in to a jar and user can not modify the classes it became "proprietary", even though it does not deviate from any of Standard JSF mechanism of hooking in to JSF Life cycle.

This is how Application Model works

  • It implements a Custom View Handler using Decorator Pattern
  • The Custom View Handler is registered in the META-INF/faces-config.xml
  • In the Custom View Handler the the Backing Page Bean corresponding to the passed in viewId is located. Locating the Backing Page Bean uses a Heuristic algorithm that depends on the relative position of JSP and Java.
  • When the Custom View Handler methods corresponding to different phase of the JSF Life Cycle is called, those methods in turn calls the corresponding methods in the Page Bean (overridden from Abstract Page Bean).

Suggestion to replace Application Model.

  • Create the AbstractPageBean in the project source tree itself.
  • Extend the PageBean with that AbstractPageBean.
  • Create the CustomViewHandler in the project source tree and register it to the faces-config.xml in the project
  • Keep a map of viewId and PaeBean class name in the CustomViewHandler. This map need to be maintained by insync Synchronizer. Ex map.put("/Page1.jsp","webapplication1.Page1.java")
  • In the View Handler, the algorithm to locate the page bean for viewId will be replace by simply obtaining it from the map.

Modify creation of DesignBean Hierarchy for JSP based JSF support

Currently, the component tree is created very strangely

  • First a flat list of DesignBean is created from the properties in the Page
  • Find the Java corresponding to the JSP page (heuristically)
  • Java Class is parsed using Java parser (Retouche)
  • Get the properties in the page using Retouche API
  • Get the Type of the property and create a DesignBean using it
  • Set the binding attribute to the DesignBean based on page name
  • From the faces-config model find the Managed Bean name corresponding to the Page
  • Create the binding signature as #{<Managed Bean name>.propertyname}
  • Then the Hierarchy of the DesignBean is created using parsed JSP tags
  • Traverse the DOM of the parsed API
  • When a Tag is visited get its binding
  • Iterate over the flat list of DesignBeans and check if the Tag binding is same as DesignBean binding.
  • If so the DesignBean of the parent tag and set this DesigBean as its child.

Unfortunately, this is a very inefficient algorithm. To find the corresponding DesignBean for a tag, the List is traversed each time. The efficiency of the algorithm is O(N2). If the page is large, then this inneficient algorithm can cause delay in opening the page.

Secondly, above algorithm mandates that each tag must have a corresponding binding property in the Java source. This bloats the Java source, adding to over all performance issue.

Parsing of JSP does not take advantage of the JSP parser in the web module.

Proposed solution

In the proposed solution, the above algorithm is ordered in the reverse way.

  • First create the DesignBean Hierarchy from JSP
  • Use the JSP Parser API (from web module) to parse the JSP
    JspParserAPI parserAPI =  JspParserFactory.getJspParser(); 
    JspParserAPI.ParseResult parseResult = parserAPI.analyzePage(jspFileOject, webModule, ERROR_IGNORE); 
    Node.Nodes  jspNodes = parseResult.getNodes();
    Node.Nodes provides a very nice visitor Pattern to visit each of the nodes.
   
  • Obtain the TagHandler Class by creating a Node visitor.
   when the node visited is  of type Node.CustomTag, then I the TagHandlerClass can be obtianed as
    Class tagHandlerClass = customTag.getTagHandlerClass()
    
  • From TagHandler class Obtain the ComponentType and create the instance
  • From the component instance create the DesignBean and set the parent accordingly (DesignBean of parent Node)
  • Finding the Component instance if the tag has binding attribute
  • Resolve the EL binding expression to find the corresponding Managed Bean
  • Parse the Managed Bean class (using retouche) and find the property corresponding to the EL binding
  • Create the component instance based on the property type
  • If the managed bean and the property is not found remove the binding and create the component from tag handler class.

<SVC>Small nit - teh beans which are only persisted in the Page bean (e.g. DataProviders) will have to be dealt with also and linked into the design bean hierarchy so that they can be shown in Outline view.</SVC>

<SVC>Currently Insync only creates the instances of the JSF components. This forces the limitation that the set of properties of the TagHandler must have a corresponding property in the Component instance so that the attributes persisted in the JSP can be modelled correctly. This convention is not followed by third party component libraries. This limits (or at least make it difficult) the use of third party component libraries in VW. To get around this problem Insync should make use of the instances of the TagHandler + Component and set the properties through TagHandler thus emulating JSF runtime.</SVC>

With above approach there is no need to add binding for each tag in the JSP. However, if the user wants to add explicit binding for a component, then we must support it. This can be done by adding a Context Item to the component called "Add binding ..".

Adding support for Visual XHTML page authoring

In a web application it is not necessary that all the pages will have data binding. Several pages could be simple content and can be simple HTML pages. Netbeans supports creation of HTML pages and some support to drag and drop HTML components on to the editor which creates code in the HTML editor

But there is no visual editing of HTML page.

Currently user can create a complete web page with out any JSF components in the JSP. However, insync still ensuring the injection of "header", "body" and "form" tags from woodstock or braveheart which is undesirable. Visual Web designer support editing of HTML tags if they are copy and pasted in the JSP.

  • They do appear in the Outline
  • Properties are displayed in the property sheet

But following are missing

  • HTML components (tags) don't appear in the Palette for drag and drop
  • Many properties displayed in the property sheet do not have property editor


With the following modification to Visual web designtime architecture, we could support HTML visual design

  • XHTML loader
  • removing insync's harcoded dependency on JSF, but with framework pluggable architecture
  • Ability to create pages from XHTML templates (NB templates not Page Templates)
  • Support in the project to create Visual XHTML pages

Additionally for rich designtime experience

  • Provide customizers and property editors
  • Provide predefined HTML only Page layouts

If we have embeded browser then it would be easy to extend the support for Dynamic HTML and javascript based web 2.0

  • Easy Mashups
  • AJAX using javascript widgets such as Dojo
  • Even support for AJAX enabled Restful Services


Adding support for facelet page authoring

As we discussed above, if user created a JSP based JSF page, then the JSP page should be parsed by JSP parser to create the DesignBean Hierarchy. However, if the page being designed is a Facelet page, them we need a parser (Facelet engine), that would parse and create the DesignBean Hierarchy from it.

What we might require to support Facelet Design

  • XHTML loader that recognizes XHTML page with Facelet tags
  • Facelet Page parser
  • Support in JSF project to add necessary hook to web.xml
  • Facelet Template based design support in the designer

Add support for other Web Technology such as PhP or Ruby

In the current Visual Web Design System, a Live DesigContext corresponding to a Visually designed Page is always constructed as a combination of Java unit (associated with Java Class) and Markup unit (associated with JSP page). The Beans Unit is associated with the Component (Design Bean) hierarchy. None of these units are pluggable based on Web technology used for that page. A pluggable architecture for the Visual Web Design system is necessary to support other Web technologies.


Pluggable support for Page rendering

Currently rendering a page is purely based on DesignBean Hierarchy and hardcoded in insync, which in fact reflects the JSF rendering technology only (calling the encodeBegin(), encodeEnd() methods of JSF components). This is limiting. Rather rendering should be delegated to the pluggable design system. If the JSF Web technology Visual Web Design System supports component based development then it would have an associated BeansUnit. Rendering can be done per bean based. But for a PhP or Ruby Web technologies, the pluggable Visual Web Design System might support full page rendering by passing it through respective engine to get the rendered HTML output.

<MD>So, is the idea to use the DataLoader to bind file mime types to specific DesignContext implementations? Are you thinking of an API/SPI pattern for modeller and renderer plugins? How does the model differ between component based systems (eg JSF) vs non-component based systems (Ruby, PHP)?

<WP> I have put my thoughts below under the sub heading "Bean Rendering Vs Page Rendering"

<SVC>The above corresponds to the box labled 2. in the attached PDF.</SVC>

Bean Rendering Vs Page Rendering

Assume a page can be split in to small units called Beans. In case of a pure HTML page, let us assume this bean is associated with a HTML tag, say a Pseudo Java Bean called HtmlBean. In case of a JSF page, this bean (actual JSF Component Java Bean called FacesBean) can be associated with actual JSF Component tag.

Each bean has a source representation, which corresponds to an unit of source in the page) and optional rendered output representation, which corresponds to an unit of Document Fragment in the rendered HTML DOM. If the bean is rendered to get that Document Fragment, then we call it Bean Rendering. The HTML Document corresponding to entire page is composed by combining these Document Fragments outputted by the tree of beans. In case of rendering the FacesBean, encodeBegin(), encodeEnd() methods are called on the Faces Component Java Bean. HtmlBean simply returns the source representation as the rendered output.

These beans are wrapped by a designtime facade called DesignBean. Visual Web Design System does not interact directly with these bean, but via DesignBean (enriched by BeanInfo and DesignInfo for rich user interaction like, customizers and property editors and even data binding).

Interestingly, in case of a pure XML tag, the tag attributes can be associated with bean properties. Using the wrapped DesignBean, these properties can be manipulated in the Design System via Custominers or property editors or DesignInfo (in case of binding). Since they have two way association , the changes in the source association (modification in the source file) will be reflected in the properties and changes in the properties (via designtime) will be reflected in the source (synchronization part by insync).

Above is the assumption in the current architecture. This may not be valid if the bean does not have direct rendered output association. So we need to support Page Rendering, as explained

Let us say we have a bean corresponding to a unit of source in the page (pseudo Java Bean called a PhPBean or RubyBean). When drag and dropped from the palette it could add bunch of source to the PhP page or Ruby Page. Since it will be wrapped by DesignBean in the Design System, it is possible to provide rich user interaction to modify the source association of this bean via Customizers and property editors. However, it does not know how to create the rendered Document Fragment. So this bean has source association but no rendered output association. In order to create the final HTML Document for the designer to display, we may have to create the complete source tree from the source association of these beans and pass through a rendering engine (PhP Engine or Ruby Engine) to get the HTML Document.

Current architectural for bean rendering can be briefed as

  • Each Page (JSP or HTML or Facelet page) is parsed to create a Page Model (FacesModel for JSP based JSF page). This constitutes the SourceUnits called JavaUnit (backing bean) and MarkupUnit (JSP).
  • The units of source in the page is converted in to corresponding tree of bean (called BeansUnit in current architecture) and then wrapped tree of DesignBean (called LiveUnit).

(Note: This is easy for JSF page or HTML page, because each tag can be directly associated with a bean (Component bean or HTML bean), we need to find a way to create the bean associated with unit of source which does not conform to this easy mapping)

  • When the DesignBean is modified, Bean Rendering is called on the DesignBean and the rendered Document Fragment is handed over to the designer which constructs the full HTML document, replacing the Document Fragment.

To support the Page Rendering we might look in to the following architectural changes.

  • When the DesignBean is modified, the PageModel should be flagged as modified and Insync Synchronizer should be notified.
  • Insync Synchronizer then calls the method PageModel.render() to get the fully rendered DOM and hand it over to Designer Controller to display the HTML in the HTML Viewer (Embedded browser ?)
  • It is up to the Page Model on how to render the full tree of source.
  • In case of PageModel that has a BeansUnit (and LiveUnit) that supports BeanRendering, then it must keep track of modified DesignBeans (removal and addition of designbean too) and then it must render only the modified design bean, replace/add/remove the corresponding Document Fragment in the buffered HTML
  • For Page Models that can support only Page Rendering, the source tree is composed from the DesignBean, and then passed through the rendering engine to create the full HTML DOM.
  • Insync Synchronizer should be agnostic to the kind of rendering employed by the Page Model.

Supporting third party components

There were several attempts to support third party components such as ADF and MyFaces components, but in vain. Following are the reasons why we could not support third party components off the shelf

  • Components must be bundled as Complib
  • There must be a designtime jar in the complib
  • The componenet class must be specified in the complib metadata
  • Complib introspect the BeanInfos corresponding to the component and gets the information to put the component in the palette
  • DesignTime System can not handle the component if there is no corresponding BeanInfo with the following hard coded entities in it
  • Tag Name
  • Tag Lib URI
  • Instance name for the component
  • Optional DesignInfo is desired for the following reason
  • Setting up the component after it is created in the Design Time.
  • Creating the sub-components if the component is a complex component such as Table Component.
  • To provide feedback in the designer and for user interaction such as customizer.
  • Data binding support
  • Design Time also expects the following
  • The Component must be a Java Bean that exactly reflects all the tag attributes of the component as properties. i.e For every tag attribute there should be a property in the
  • The component must have a style property and style attribute in the tag (to support grid layout)

Suggested solution and enhancement

(mainly for JSF component import)

User must be able to import the components in to the palette simply from the component jar. There should not be a mandatory need for Complib. In case of JSF components, the import dialog should be able to inspect the faces-config.xml to get the list of components. If the optional designtime jar is also provided, then get the BeanInfo based on the components found from the faces-config.xml and get additional information.

Currently, DesignTime System solely depends on Component properties and its BeanInfo to create the DesignBean. The source representation is composed from the BeanInfo supplement data (Tag Name, Taglib URI, instance name). In order to support the components with out the mandatory explicit BeanInfo, DesignTime system must able to obtain the necessary information from the Tag Library description file, such as the Tag Name, Taglib URI and attributes.

Finally, now the only way to inject the requisites for richer designtime experience is via DesinInfo. However, we must at least provide some simple way, may be using some XML file with predefined schema.

Data binding enhancements

Dataprovider is one of the main mechanism to bind data to the components. Eventhough, dataprovider is nothing but a thin API to support uniform way for the components and DesignTime System to interact, it can be consider proprietary, since it introduces "non standard" API with package name "com.sun.rave.data.*" in the source. It may be possible to hide the dataprovider, so that the user need not have to know about the dataprovider externally. This is already accomplished for table component.

May in the future, we should

  • Promote Java Persistence API as the main data access mechanism
  • The DesignTime System must be able to bind collection of POJOs to components
  • When database table is drag and drop bind using JPA than CachedRowset
  • Complete designtime support to create Entity Bean and corresponding Controller for binding

Finally, we must get rid of the need for a live database connection even after the table is bound to the component. One solution for this is to use only JPA for binding. If Cachedrowset need to be supported for backward compatibility, then database schema should be persisted in the project for offline access later.


Improving Design Time EL expression Resolver

In order for the designer to display the PDL (Page Description Language such as JSP, XHTML, PHP etc), the PDL need to be rendered to create the HTML DOM, the designer can display. The PDL tags might contain EL expressions such as JSF Value binding. In such cases, these EL expressions need to be resolved at designtime. During runtime Java EE 5 EL implementation takes care of the resolving.

In the current architecture, to resolve JSF Value Binding Expressionss, VW Design System (JSF Designtime Container) delegates teh task to JSF Reference Implementation. Which in turn creates a Composite EL resolver and registers with the JSP EL Context for reoslving the variable and property.

Visual Web Design System has its own Design Time Variable Resolver and Design Time Property Resolver which it registers to the JSF RI via faces-config file. RI collects the faces-config files in the jars from the ClassPath scanning.

The problem here is most of the designtime EL resolving happens via these two Design Time Resolvers. However, the whole task is routed via JSF RI and JSP ELContext. To resolve the Expression JSP ELContext runs the EL Expression through the chain of EL resolvers registered with it until a particular EL resolver (in this case Designtime resolvers) could resolve the expression.

Design Time Resolvers closely work with the Design Time System (via Designtime API) to get the corresponding Design Bean and design property to resolve the expression.

In order to improve the performance and efficiency of resolving the EL expression, the better solution would be directly resolving them in the Designtime System itself (mocking up the ELContext and closely woking with the Bean Unit).

Another problem is, these resolvers can work only with objects. So any new classes added to the project need to be compiled and available in the classpath for the resolvers to correctly resolve them (http://blogs.sun.com/winston/entry/objectlistdp_sample_project). We could improve this area by making the designtime resolvers to work directly with retouche and do a source modeling of classes for which the sources are available in the project.

Improving Page rendering error

Several times when the project is opened, the pages would come up with page rendering error message. This is very annoying. Most of the times the rendering error is from EL Expression resolvers, because it could not resolve the binding in the components, either because the corresponding database connection is not available or the variables or properties could not be resolved.

One possible solution is to make the designtime resolver smart enough to handle such situation. These resolvers could send back some error message or the binding expression itself as the value for the EL expression. This way the page will display all the components, but with data that hints the user something is wrong. May be designer could badge such compoenents with an error badge. The exception window should show the exceptions corresponding to the EL expression resolving error.

I looked at other tools such as Visual Studio for Web development. It marks the data of such components as simply #Undefined.

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo