Modification History:
October 31, 2007 - Winston Prakash
October 24, 2007 - Sandip Chitale
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 includesUnfortunately, 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
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
<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.
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
Suggestion to replace Application Model.
Currently, the component tree is created very strangely
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.
In the proposed solution, the above algorithm is ordered in the reverse way.
<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 ..".
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.
But following are missing
With the following modification to Visual web designtime architecture, we could support HTML visual design
Additionally for rich designtime experience
If we have embeded browser then it would be easy to extend the support for Dynamic HTML and javascript based web 2.0
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
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.
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>
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
To support the Page Rendering we might look in to the following architectural changes.
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
(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.
May in the future, we should
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.
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.
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.
| visualweb.next.pdf | ![]() |
162360 bytes |