指定完整类名在各类开发配置中经常用到,特别在基于框架的开发中非常频繁,一般在Eclipse IDE中的操作就是:在PackageExplorer或者Project Explorer中展开类结构树->Right Click->Context Menu->Copy Qualified Name。我在想能不能偷懒一步呢?如果不展开类结构树,默认的Copy Qualified Name命令复制得到的是相对于workspace的absolute path (以/作为起始)。并且,对于classpath下的资源执行Copy Qualified Name命令得到的也是相对于workspace的absolute path。实际开发中,很少需要这样的absolute path,需要的更多是相对于classpath下relative path。需求又来了,考虑添加一个自定义的命令到Eclipse中去。
很遗憾的是,尝试写一个自定义的Eclipse Plugin时,得到如下错误。MS无法获取无法加载到JDT的类。对Eclipse的class loader机制不太熟悉,也不去过多深究。只想尽快达到最初目的,于是,直接对Eclipse的JDT直接进行修改。还好,Eclipse目录下自带JDT的source,仔细查看源码改起来也不麻烦,虽知道这不是正道。
Caused by: java.lang.ClassNotFoundException: org.eclipse.jdt.core.ICompilationUnit
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:506)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:422)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:410)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
... 35 more
对JDT的Jar搜索一下"Copy Qualified Name"就能很快定位到位于org.eclipse.jdt.internal.ui.actions.CopyQualifiedNameAction中的关键代码。可以见到代码采用了getFullPath()。
private String getQualifiedName(Object element) throws JavaModelException {
if (element instanceof IResource)
return ((IResource)element).getFullPath().toString();
if (element instanceof IJarEntryResource)
return ((IJarEntryResource)element).getFullPath().toString();
if (element instanceof IJavaProject || element instanceof IPackageFragmentRoot || element instanceof ITypeRoot) {
IResource resource= ((IJavaElement)element).getCorrespondingResource();
if (resource != null)
return getQualifiedName(resource);
}
return TextProcessor.deprocess(JavaElementLabels.getTextLabel(element, LABEL_FLAGS));
}
对JDT代码进行了一番研究后,修改成如下:
private String getClassNameFromJavaFile(String javaElementName) {
if(javaElementName.endsWith(".java")) {
return javaElementName.substring(0, javaElementName.length() - 5);
} else if (javaElementName.endsWith(".class")) {
return javaElementName.substring(0, javaElementName.length() - 6);
} else {
return javaElementName;
}
}
private String getQualifiedName(Object element) throws JavaModelException {
// 1 java file
if (element instanceof ICompilationUnit) {
ICompilationUnit compilationUnit = (ICompilationUnit)element;
IPackageDeclaration[] packages = compilationUnit.getPackageDeclarations();
if(packages != null && packages.length > 0) {
return packages[0].getElementName() + "." + getClassNameFromJavaFile(compilationUnit.getElementName());
} else {
return getClassNameFromJavaFile(compilationUnit.getElementName());
}
}
// 2. Package下的resource file
if (element instanceof IResource) {
IResource resource = (IResource)element;
IContainer container = resource.getParent();
IJavaElement javaElement = null;
if (container.getAdapter(IJavaElement.class) != null) {
javaElement = (IJavaElement)container.getAdapter(IJavaElement.class);
}
if( javaElement != null ) {
IPackageFragmentRoot packageRoot = (IPackageFragmentRoot)javaElement.getAncestor(IJavaElement.PACKAGE_FRAGMENT_ROOT);
return resource.getProjectRelativePath().makeRelativeTo(
packageRoot.getResource().getProjectRelativePath()).toString();
}
return resource.getFullPath().toString();
}
// 3. Jar包中的class file
if(element instanceof IClassFile) {
IClassFile classFile = (IClassFile)element;
IPackageFragment packageFragment = (IPackageFragment)classFile.getAncestor(IJavaElement.PACKAGE_FRAGMENT);
if(packageFragment != null) {
return packageFragment.getElementName() + "." + getClassNameFromJavaFile(classFile.getElementName());
}
}
// Jar包中的resouce file
if (element instanceof IJarEntryResource) {
return ((IJarEntryResource)element).getFullPath().toString().substring(1);
}
if (element instanceof IJavaProject || element instanceof IPackageFragmentRoot) { // || element instanceof ITypeRoot
IResource resource= ((IJavaElement)element).getCorrespondingResource();
if (resource != null)
return getQualifiedName(resource);
}
return TextProcessor.deprocess(JavaElementLabels.getTextLabel(element, LABEL_FLAGS));
}
本人加入若干判断分支并对原有代码做了修改,分别对应于不同元素类型的Copy Qualified Name
1)Package下的java file
2)Package下的resource file
3)Jar包中的class file
4)Jar包中的resouce file
代码看起来有点恶心,类型转换绕来绕去。不知有没有更简洁的~~~姑且这样,经我本地Eclipse测试反正是可以的。打包也是恶心,把改完编译好的class file重新塞进本地Eclipse的Plugin目录下的org.eclipse.jdt.ui_3.6.1.r361_v20100825-0800.jar中去。重新打开Eclipse,大功告成,顺便设置了快捷键。效果如下:
- 大小: 35.5 KB
- 大小: 30.4 KB
- 大小: 42.2 KB
- 大小: 30.1 KB
分享到:
相关推荐
用Copy Qualified Name复制类全名时 总是这样的/hb03/src/org/self/hb/entity/Account.java很不方便 可以这样解决 : 下载插件解压到Eclipse安装目录下 将那一个解压后的文件夹直接丢进安装目录下面的Myeclipse\...
java源码补丁生成器 使用说明: 01、设置文件路径resource/filePath.properties ... 0202、升级文件列表也可在eclipse中右键文件选择 Copy Qualified Name 复制文件全路径 03、执行start.bat文件生成补丁
解决使用unittest时遇到的问题---Provide a qualified name of function, class or a module
为了实现"Copy Fully Qualified Class Name"这样的功能,我们需要将特定的插件添加到Eclipse中。在这个案例中,提供的压缩包`de.jave.eclipse.copyfully_1.1.0`很可能就是这样一个插件,它扩展了Eclipse的功能,允许...
- **Eclipse**: 右击--> `CopyQualifiedName` (右击--> `Copy Reference`) - **Android Studio**: `Ctrl+Shift+Alt+C` - **功能说明**: 复制类的完整路径,包括包名和类名。 **38. 大写/小写** - **Eclipse**: `...
首先,在Eclipse中创建一个新的Web项目,命名为`WSServer`。接下来,创建一个Java包`com.shi.service`,并在该包下编写一个名为`WSTest`的服务类。 ##### 类定义 ```java package com.shi.service; /** * 服务类 ...
- 打开 Eclipse 并选择 `Window > Preferences`,在弹出的窗口中选择 `Java > Installed JREs`。 - 点击 `Add` 按钮,然后选择 `Standard VM`。 - 在 `JRE home directory` 中,指定 JDK 安装目录下的 `jdk1.6.0_...
Eclipse UML插件是一种用于Eclipse IDE的扩展工具,它允许开发者在Eclipse环境中创建、编辑和维护UML(Unified Modeling Language)模型。这种插件对于软件开发人员来说非常有用,因为它提供了可视化的界面来帮助...
它包括一个高性能堆栈(通道,序列化,数据结构,安全性)以及在堆栈顶部构建的客户端和服务器SDK。 堆栈溢出标签: 邮件列表: : Maven建筑米洛使用JDK 8 ,从项目根目录运行mvn clean install 。发布版本发布到...
htmi页面 是打印产品合格证的html,我这有源码!
目标受众:这份指南主要面向已经对Tableau Desktop 10功能有全面理解并且至少有五个月时间在该产品中应用所学知识的用户。 先决条件:参加此考试无须任何先决条件,任何用户均可报名参加。 考试细节:考试的详细...
首先,需要在 ESXi 5.0 中安装 iSCSI software initiator,然后配置 iSCSI 目标的 IP 地址和 iSCSI Qualified Name。接着,需要在 ESXi 5.0 中创建 iSCSI 存储设备,并将其添加到虚拟机中。 iSCSI 存储是 VSphere ...
求系统的时域性能指标的函数,给定系统的数学模型,不错的
你可以创建一个`Item`类,然后在`parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)`中开始创建新的`Item`实例,在`parser(_:foundCharacters:)`中收集属性值,并在`parser(_:didEndElement:...
标题“qualified_dicoms.zip”指的是一个包含合格 DICOM(Digital Imaging and Communications in Medicine)格式的图像数据的压缩文件。DICOM 是医学成像领域广泛使用的标准,它允许医疗设备和软件之间交换和共享...
在iOS开发中,XML(eXtensible Markup Language)是一种常用的数据交换格式,它结构清晰、易于阅读,常用于Web服务、配置文件等场景。`NSXMLParser`是Apple为iOS和macOS提供的一个XML解析器,允许开发者解析XML文档...
在彩票中,大底通常指的是一个包含多个可能中奖号码的组合,比如在双色球中,一个大底可能包括所有红球和蓝球的组合。而“交集”则涉及到对多个大底进行筛选,找出它们共有的号码或者组合,以提高中奖的可能性。 ...
如`parser:didStartElement:namespaceURI:qualifiedName:attributes:`会在解析到元素开始时调用,`parser:foundCharacters:`用于处理元素内容,`parser:didEndElement:namespaceURI:qualifiedName:`则在元素结束时被...
在iOS开发中,Objective-C(简称OC)是主要的编程语言之一。XML(eXtensible Markup Language)是一种用于存储和传输数据的标准格式,广泛应用于网络服务和数据交换。本教程将详细介绍如何在OC中解析XML数据并将其...
在iOS开发中,XML(eXtensible Markup Language)是一种常用的数据交换格式,它用于存储结构化数据。本文将深入探讨如何使用GDataXMLParser库在iPhone应用中解析XML文件。GDataXMLParser是Google提供的一款强大的XML...