月蚀传说

浮躁让人失去理智
posts - 25, comments - 101, trackbacks - 0, articles - 0
  BlogJava :: 首页 ::  :: 联系 :: 聚合  :: 管理

扩展WTP2.0图形化Web编辑器——转换器

Posted on 2007-11-08 23:35 Dart 阅读(5270) 评论(13)  编辑  收藏 所属分类: GEFJSFEclipse
1.概述

新的WTP2.0带了一个叫做WebPageEditor的编辑器,打开一开,不得了,是带图型的编辑器耶~~
既然有了这个功能,那它肯定有扩展机制,能够让我们把自己的Taglib标签通过该编辑器的图形功能显示出来。
注意:此文认为阅读者都已经具备了最基本的Eclipse Plugin开发能力。示例项目下载

2.如何扩展

WebPageEditor的如何工作的倪?其实它的工作原理很简单。
首先它支持了对最基本的HTML元素的现实功能,然后如果需要显示我们自己定义的Tag的话,则要将这个自定义的Tag转换成普通的HTML模型。



下面我们开始做一个例子。
首先我们建一个简单的TLD文件,我们命名为:mytest.tld.我们在这个文件中定义一个mybutton标签,它具有三个属性,text,width,height。
我们这么规定该标签在页面上的显示:基本现实为一个按钮,按钮上的文字是根据text值来确定的,该按钮的大小则是由width和height值来确定的:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<taglib>
    
<tlib-version>1.0</tlib-version>
    
<jsp-version>1.0</jsp-version>
    
<short-name>m</short-name>
    
<uri>http://mytagconvert.com</uri>
    
<description>test</description>
    
<tag>
        
<name>mybutton</name>
        
<tag-class>null</tag-class>
        
<tei-class>null</tei-class>
        
<body-content>empty</body-content>
        
<description>test</description>
        
<attribute>
            
<name>text</name>
            
<required>false</required>
            
<rtexprvalue>false</rtexprvalue>
        
</attribute>
        
<attribute>
            
<name>width</name>
            
<required>false</required>
            
<rtexprvalue>false</rtexprvalue>
        
</attribute>
        
<attribute>
            
<name>height</name>
            
<required>false</required>
            
<rtexprvalue>false</rtexprvalue>
        
</attribute>
    
</tag>
</taglib>


然后我们新建一个动态web项目,然后新建一个JSP文件,用WebPageEditor打开它,你会发现,画板中仅仅只有HTML的工具栏:



肯定有人会问:工具栏就只有HTML和jsp,怎么创建我所需要的拖拽我自定义的标签啊!

别急,这里我说一下。WebPageEditor的工具栏跟所编辑的页面所在项目中,能够读到的TLD文件是有关系的(准确说应该是这个项目的classpath能够读到的TLD)。就是说,如果你在该项目下放有一些TLD文件,那当你打开WebPageEditor的时候,它会自己读到这些TLD文件(必须保证这些文件能够被读出来),然后根据TLD文件中对tag的定义,再在画板上显示出所能绘制的tag标签工具Entry。所以,我们这个例子也需要将刚才建好的那个test.tld文件放置到这个项目中去。然后我们重新用WebPageEditor打开新建好的JSP文件,你会发现,工具栏中出现了我们刚才所定义好的那个tld:



你可以试着把工具栏中的TestButton托到编辑器中,不过它显示出现的是一个空白的玩意儿,上面还有该标签的名称。
ok,准备工作算是做好了,现在我们开始真正讨论如何让自定义标签可以显示,而且还能进行编辑。

首先让我们看一个扩展点:
org.eclipse.jst.pagedesigner.pageDesignerExtension
这个扩展点就是我们需要扩展的。下面几个元素比较重要:

tagConverterFactory
elementEditFactory
attributeCellEditorFactory

我们目前只讨论tagConverterFactory,其他的扩展点会在以后进行讲解。

tagConverterFactory有一个属性值:class。这个class是需要我们给出一个实现了org.eclipse.jst.pagedesigner.converter.IConverterFactory接口的类。

这个接口有两个方法需要我们实现:

getSupportedURI
这个方法什么意思呢?打开TLD文件,大家可以看到,TLD文件中有一个URI的属性值,这个属性值我们可以看成是XML文件中Schema的名字空间,用来唯一确定该TLD文件的一个标识。WebPageEditor需要我们给出这么一个URI,其目的很明显,就是能够和它将读出的TLD进行匹配。

createConverter
这个方法有点让人很茫然,首先看它的参数:
Element element,int mode
第一个参数element是指,在我们拖拽进入一个标签后,该标签对应的element模型;mode是指现实模式,前面忘记说了,WebPageEditor是多页编辑器,一页是编辑页面的,一页是预览页面的。这里的mode就是指在编辑页面模式还是预览页面模式。我们现在可以不考虑这个参数,在下面的所有文字中,该mode参数一律被视为编辑页面模式。
该方法返回的是一个ITagConverter接口。
可以说,ITagConverter接口诠释了WebPageEditor的如何对标签进行解析并形成一个图形的过程。根据上面我们给出的一个简单的流程图可以看出,ITagConverter其实就是专门转换taglib中定义的tag到标准HTML DOM的这么一个接口类。

话说多了是水,先看看怎么实现把。
先罗嗦一下步骤:
1.新建一个插件项目,加入依赖项:
  org.eclipse.jst.pagedesigner,
  org.eclipse.wst.sse.core,
  org.eclipse.wst.xml.core
2.新建一个为mybutton标签进行转换的Converter类
3.新建一个映射标签名和Converter的ConverterFactory类
4.建立一个在插件项目中实现刚才提到的 org.eclipse.jst.pagedesigner.pageDesignerExtension 扩展点


新建项目我不就不说了。从新建Converter说起。

3.MyButtonTagConverter

一般情况下,我不建议大家直接实现ITagConverter,很累人的,而且其实里面还有很多需要考虑的东西。所以我们应该从一个抽象类开始继承:
AbstractTagConverter。
这个类实现了大部分ITagConverter的功能,并且还提供了好些方法可供使用,它只将转换DOM的这个工作利用一个抽象函数 doConvertRefresh暴露出来——
doConvertRefresh函数的返回值就是我们最终转换成的DOM。
另外两个抽象函数是isMultiLevel和isWidget,这两个以后介绍。

我们继承这个类后只要将doConvertRefresh函数实现就可以了。
刚才我们新建了一个TLD文件,里面描述了一个mybutton标签,现在我们来实现这个标签的转换。
新建一个类,名为MyButtonTagConverter,然后我们实现这个类的doConvertRefresh方法:


public class MyButtonTagConverter extends AbstractTagConverter{

    @Override
    
protected Element doConvertRefresh() {
        
// 创建一个HTML 的button element
        Element button  = createElement(IHTMLConstants.TAG_BUTTON);
        
// 获得属性值
        String text = getHostElement().getAttribute("text");
        
if(text == null) text = "";
        
// 将text值给button,作为button的content,以便显示
        button.appendChild(createText(text));
        
// 将host element的属性全部复制给新建的button element中:
        JSFConverterUtil.copyAllAttributes(getHostElement(), button, null);
        
return button;
    }
}

我说一下这几个方法:
createElement
这个方法是AbstractTagConverter提供的,它是专门用于创建一个DOM元素的方法,传入的值则是生成该DOM得元素名,这里我用到了一个维护常量的类IHTMLConstants,它是JST提供的,很有用。如果你有兴趣可以看看AbstractTagConverter如何实现这个方法的,很简单,但是很麻烦。

getHostElement
这个方法是AbstractTagConverter提供的。返回的是一个被称为host element的DOM对象,什么是host element?它就是我们在页面上写的那个<mybutton/>的dom对象。

createText
这个方法是AbstractTagConverter提供的。创建一个content节点

JSFConverterUtil.copyAllAttributes
一个工具类提供的复制属性的方法。很实用。之所以要进行复制所有的属性,是因为,我们单独创建按出来的HTML DOM只是一个光秃秃的东西,不具备任何属性,那么host element的属性值有一部分是可以赋给生成的HTML DOM的,比如说,代码中给出了这么一段:读出host element的text属性值,然后给button dom的  属性,这样它就可以显示出文字来了,而其他一些属性名相同的属性,在host element和生成的html dom中具有相同的功效,我们是需要复制过来的。

我们可以这么想:
我们所写的<mybutton text="button"/> 被转换成了<button>button</button>HTML dom。

4 MyTagConverterFactory

这个类很简单:
public class MyConverterFactory implements IConverterFactory {

    
/* (non-Javadoc)
     * @see org.eclipse.jst.pagedesigner.converter.IConverterFactory#createConverter(org.w3c.dom.Element, int)
     
*/
    
public ITagConverter createConverter(Element element, int mode) {
        String name 
= element.getLocalName().trim();
        
if(name.equalsIgnoreCase("mybutton")){
            
return new MyButtonTagConverter(element);
        }
        
return new DefaultUnknownTagConverter(element,mode);
    }

    
/* (non-Javadoc)
     * @see org.eclipse.jst.pagedesigner.converter.IConverterFactory#getSupportedURI()
     
*/
    
public String getSupportedURI() {
        
return "http://mytagconvert.com";
    }

}

这里需要强调的是三点:
1.getSupportedURI方法返回的URI必须和TLD里的一致。
2.返回的Converter的构造函数的参数必须给出,因为这个参数就是我们要的Hostelement,而
createConverter传进的element正好就是这个host lement。
3.不要让createConverter返回null,给出一个默认的Converter

5 写好扩展点

我们新建一个
org.eclipse.jst.pagedesigner.pageDesignerExtension,然后写好tagConverterFactory元素,将它的class设成我们新建好的MyTagConverterFactory:

   <extension
         
point="org.eclipse.jst.pagedesigner.pageDesignerExtension">
      
<tagConverterFactory
            
class="tagconverters.MyConverterFactory">
      
</tagConverterFactory>
   
</extension>

6.运行

让我们运行这个插件。
在运行后,建立一个动态的web项目,然后把我们的tld文件复制到项目的WebContent下。再新建一个jsp文件,用WebPageEditor打来,然后我们再将右侧画板上的mybutton拖入编辑器:



怎么样,不错吧。

7.未完待续

其实这只是一个开始,记得一开始为什么我会将mybutton设置上width和height,但后面就没说了,这些都要留到后面。
后续文章我还会讲一些其他的东西,比如如何扩展IElementEdit、属性的页、Palette的显示等等。
谢谢大家,再见。



评论

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2007-11-20 15:31 by jerryyu
恩。好东西。我看到Myeclipse的jsfDesigner 就是基于jst.pagedesigner.
可以研究一下com.genuitec.eclipse.jsf.designer.

# re: 扩展WTP2.0图形化Web编辑器——转换器[未登录]  回复  更多评论   

2007-12-05 10:04 by 鬼谷子
不错,留名先~
WTP终于支持可视化编辑了~

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2007-12-05 10:07 by 鬼谷子
晚上回去下了来,研究一下。
有什么问题,还请多多指教啊~

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-05-08 11:03 by
写得很好!!!楼主辛苦了

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-08-13 10:05 by Stringle
感谢楼主的分享,值得研究!

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-09-12 15:51 by 76814055@qq.com
大哥,您的后续什么时候能出来?本来想好好学习一下的。
wtp3.0都发布了!

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-09-13 21:18 by Dart
to 76814055 :

不会再有续了,没多少人关注这个,我也不想写了,你可以看看文章第一次post的时间,再看看回复数量就知道我的心情了,哇凉哇凉的。

不过如果你有兴趣可以关注另外一个Web图形编辑器:JBoss VTP,这个可比WTP的要好很多。

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-09-16 14:46 by 76814055@qq.com
我觉得并不是没人关注,有好多人转了你这篇文章呢!你自己搜一下,就知道了!不过我也承认我们新手都会有些后知后觉。这并不是常用的扩展点,但我觉得这个扩展点和org.eclipse.ui.navigator.navigatorContent很像,很方便就可以扩展但是大多人不知道,所以不是很受关注。但并不是说这个扩展点没有精彩之处。
让我要命的是这个扩展点因为没有确定下来,竟然没有说明!郁闷的连实现哪个接口都要找半天。(也许是我这个新手太无知了)前些天偶然看了您这篇文章才知道原来这么简单,所以很感激您!希望这迟来敬佩之情能弥补一些您哇凉哇凉的心。(^_^)
等我完成我自己的扩展后的Web图形编辑器后,我会尽力去总结一下写一篇这个扩展点的完整介绍。当然还会转载您的这篇文章。

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-09-18 17:57 by Dart
你要这么一说我真有点不好意思了,不想写的所谓原因可能我是在找借口吧,主要还是我太懒了-____,-

如果需要我会立即动手写新的文章,或者可以一起讨论一下。不过我更希望你能关注一下JBoss VTP。

我的email:black_frezee@163.com

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-10-06 16:45 by 76814055@qq.com
我晕死了,找了好久,你说的应该是JBoss VTE吧。。。
它也是在这个框架上扩展而来吧!我正在看,不过它每拖一下标签就谈出一个页面,用多了有点烦!

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2008-12-03 17:47 by douya
我用的时候也是点Palette的时候就弹,我做是的在点编辑器的时候弹.实现方式可能会过几天在ibm developerwork上发表(理想情况下呵呵),就是扩展一下org.eclipse.jst.pagedesigner.pageDesignerExtension扩展点....


看到这篇文章我对我的文章发表有信心了,学习到了不少东东!谢谢彭哥,今天一口气给你发了那么多邮件别生气啊,下次我会注意的

PS:貌似我已经注意了,要不估计你邮箱现在早暴了,哈哈

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2010-12-31 09:46 by emmy
楼主辛苦了,对我很有用处,正好在找这方面的资料。谢谢了!

# re: 扩展WTP2.0图形化Web编辑器——转换器  回复  更多评论   

2012-02-09 21:32 by Agustin
I don't understand what associate this file tld with pagedesigner point extenssion . Could you explain?

只有注册用户登录后才能发表评论。


网站导航: