原创作者: grid.qian   阅读:1480次   评论:2条   更新时间:2011-06-01    
最近由于工作需要,学习了ECLIPSE的COMPARE插件,并利用它进行了两个String的比较.

相关资料:
http://wiki.eclipse.org/FAQ_How_do_I_create_a_Compare_dialog%3F
http://wiki.eclipse.org/FAQ_How_do_I_create_a_compare_editor%3F
http://wiki.eclipse.org/FAQ_How_can_I_use_and_extend_the_compare_infrastructure%3F

另外ECLIPSE本身有一些对COMPARE扩展得例子,可以从网站上下载.比如说org.eclipse.compare.examples, org.eclipse.compare.examples.xml两个插件分别扩展了COMPARE插件使得可以对JAVA的PROPERTY文件和 XML文件进行比较.这两个例子插件都是扩展COMPARE PLUGIN,使用EDITOR来显示COMPARE结果.大家可以去看源代码,这里就不多说了.

下面主要说一下我自己做的部分.
复用COMPAREDIALOG,来比较自己的东西,有两种途径:一种是继承CompareEditorInput写一个自己的INPUT,一种是实现CompareItem类.
我使用的是第一种途径.
CompareConfiguration cc = new CompareConfiguration();
cc.setLeftLabel();
cc.setRightLabel();
CompareEditorInput finput = new MyCompareInput(cc);
首先建一个CompareConfiguration.这是个配置类,我们可以使用它来指定Comparedialog上显示得一些东东.比如说我们可以设置用来显示互相对比的两个字符串的左右两个文本框的label(如上所示).
然后我们可以用这个配置类来构建自己的INPUT类.比如说这里是MyCompareInput.
这个类继承CompareEditorInput,这样才能作为openCompareDialog得输入.
CompareUI.openCompareDialog(finput);
这样就可以打开ECLIPSE的COMPAREDIALOG进行实际的比较了.
在MyCompareInput中我们需要提供一个方法来接受传入的要进行比较得两个东西.比如说我们在工作区中选了两个文件,想要比较它们.我们就可以实现一个setSelection方法接受传入得selection,然后再来得到这两个文件.
我这里用了一个setStrings方法,来传入两个要比较的字符串.
在MyCompareInput中最重要得要实现的方法是prepareInput,比较字符串就是在这个方法里去比较得.
这这个方法中,比较得任务是由Differencer类去完成.这个类ECLIPSE已经帮我们完成了.
Differencer d = new Differencer() {
protected Object visit(Object parent, int description,
Object ancestor, Object left, Object right) {
return new DiffNode((IDiffContainer) parent, description,
(ITypedElement) ancestor, (ITypedElement) left,
(ITypedElement) right);
}
};
使用时我们只需药实例化这个类或者根据需要继承这个类.
Differencer d = new Differencer();
实际得比较是用了Differencer的findDifferences方法.所以我们只需要用要进行比较的两个字符串,分别构建一个实现ITypedElement接口的类,传进findDifferences去就行了.
d.findDifferences(false, pm, null, null, fLeftResource,fRightResource);
fLeftResource,fRightResource就是我们实现了ITypedElement得源.作为要进行比较的源,我们还需要实现 IStreamContentAccessor接口.IStreamContentAccessor接口只有一个需要实现的方法createStream,ECLIPSE用它来把要比较的东西构建成一个输入流.这样COMPARE比较框架才能够去一点一点的比较.下面是我实现得 fLeftResource的类.
class MyCompareNode extends BufferedContent implements ITypedElement {

private String fResource;

MyCompareNode (String resource) {
fResource = resource;
}

protected InputStream createStream() throws CoreException {
InputStream is = null;
is = new ByteArrayInputStream(fResource.getBytes());
return is;
}

public Image getImage() {
return null;
}

public String getName() {
return null;
}

public String getType() {
return ITypedElement.TEXT_TYPE;
}
}
针对不同的比较对象,createStream方法可以使用不同的方法来得到InputStream,只要能构建成InputStream, eclipse就能进行比较.另外getType方法可以返回三种类型:FOLDER_TYPE,TEXT_TYPE,UNKNOWN_TYPE.可以根 据需要自己选择.
构建完prepareInput方法,我们就完成了全部工作.就可以利用COMPARE框架来比较我们自己的东西了.

另一种方法是实现CompareItem类.这个可以去看
http://wiki.eclipse.org/FAQ_How_do_I_create_a_Compare_dialog%3F
eclipsefaq中有个例子CompareStringsAction .
这里的CompareItem也是需要实现IStreamContentAccessor,ITypedElement两个接口的.
public class CompareStringsAction implements IWorkbenchWindowActionDelegate {
private static final int SECS_PER_YR = 60 * 60 * 24 * 365;
private ResourceBundle messages = ResourceBundle
.getBundle("org.eclipse.faq.examples.actions.CompareMessages");
private final Random rand = new Random();
private IWorkbenchWindow window;
public void dispose() {
}
private long getRandomDate() {
return System.currentTimeMillis() - (1000 * ((long)rand.nextInt(SECS_PER_YR)));
}
private String getRandomString() {
int len = rand.nextInt(200);
StringBuffer buf = new StringBuffer(len);
for (int i = 0; i < len; i++) {
buf.append((char) ('a' + rand.nextInt(26)));
}
return buf.toString();
}
public void init(IWorkbenchWindow window) {
this.window = window;
}
/**
* Opens a dialog allowing the user to select one from a group of random
* strings. The resulting selection is then displayed in a message dialog
*/
public void run(IAction action) {
//create several random string editions
final int count = rand.nextInt(20) + 5;
CompareItem[] items = new CompareItem[count];
for (int i = 0; i < items.length; i++)
items[i] = new CompareItem("String " + i, getRandomString(),
getRandomDate());
EditionSelectionDialog dialog = new EditionSelectionDialog(window
.getShell(), messages);
ITypedElement result = dialog.selectEdition(items[0], items, null);
if (result == null)
return;
String value = ((CompareItem) result).getString();
MessageDialog.openInformation(window.getShell(), "Your selection is...",
value);
}
public void selectionChanged(IAction action, ISelection selection) {
}
}

class CompareItem
implements
IStreamContentAccessor,
ITypedElement,
IModificationDate {
private String contents, name;
private long time;
CompareItem(String name, String contents, long time) {
this.name = name;
this.contents = contents;
this.time = time;
}
CompareItem(String name, String contents) {
this(name, contents, System.currentTimeMillis());
}
public InputStream getContents() throws CoreException {
return new ByteArrayInputStream(contents.getBytes());
}
public Image getImage() {
return null;
}
public long getModificationDate() {
return time;
}
public String getName() {
return name;
}
public String getString() {
return contents;
}
public String getType() {
return ITypedElement.TEXT_TYPE;
}
}
评论 共 2 条 请登录后发表评论
2 楼 zsh1120 2010-10-01 12:49
为这事,郁闷了两天了,谢谢!!!
1 楼 zsh1120 2010-10-01 12:48
太谢谢了,正需要这方面的资料!!!!

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics