首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Eclipse开发 >

eclipse 源码略读

2012-07-25 
eclipse源码泛读eclipse的入口插件:org.eclipse.platform ?产品的定义,用到的图标,外观的定义都在这里,plu

eclipse 源码泛读

eclipse的入口插件:

org.eclipse.platform ?

产品的定义,用到的图标,外观的定义都在这里,plugin.xml绑定一个application

这里没有代码,只是样式、图标。

org.eclipse.ui.ide.application

该插件是eclipse的真正入口,

主要的类有:

IDEApplication.java ? ?IDEWorkbenchAdvisor.java ??IDEWorkbenchWindowAdvisor.java?

ResourcePerspective.java ?

这几个类大家应该都很属性。

不过没有ActionBarAdvisor的定义,说明eclipse中所有的菜单、工具栏,在启动的时候是为空的。

里面的菜单都是其它插件扩展得到的。

?

接下来进入org.eclipse.core.runtime ?看看。

?

这里主要用到了 ?osgi ?equinox ? ?java.io ?java.net ?

?

Platform ?对该类进行了包装 ?InternalPlatform ? ? ?

InternalPlatform ? ?中使用了个单利模式。

eclipse 也大量运用了单利模式。

?

public IAdapterManager getAdapterManager() {

assertInitialized();

return AdapterManager.getDefault();

}

?

查看代码可知 ?如何名称相同的bundle 会返回第一个被加载的bundle。

?

public Bundle getBundle(String symbolicName) {

PackageAdmin packageAdmin = getBundleAdmin();

if (packageAdmin == null)

return null;

Bundle[] bundles = packageAdmin.getBundles(symbolicName, null);

if (bundles == null)

return null;

//Return the first bundle that is not installed or uninstalled

for (int i = 0; i < bundles.length; i++) {

if ((bundles[i].getState() & (Bundle.INSTALLED | Bundle.UNINSTALLED)) == 0) {

return bundles[i];

}

}

return null;

}

?

?

该插件也相当于eclipse的 发动机了,服务的启动、停止、文件的加载等,都是在这里处理的。

?

?

下了看一下 ??org.eclipse.ui ?插件。

该插件有点出乎意料

只有两个类UIPlugin ??UIPreferenceInitializer

?

UIPlugin ? 中用到了 ?PrefUtil ?这个类是对preferences操作的一个工具类,用着还是很方便的。

PrefUtil .getInternalPreferenceStore(); 直接得到 系统?IPreferenceStore

?

UIPreferenceInitializer 为eclipse ?初始化一些参数,它是在这里定义的。

?

? ?<extension

? ? ? ? ?point="org.eclipse.core.runtime.preferences">

? ? ? <initializer

? ? ? ? ? ? src="/img/2012/06/25/111422766.bmp">

在看NewWizardAction 源码中看到了

LegacyResourceSupport类,这个类就是加载不同插件的class的。

这里也说明了不同插件(Bundle)是通过不同的类加载器加载的。

?

?

?IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault()

? ? ? ? ? ? ? ? .getDialogSettings();

通过IDialogSettings ?可以对wizard的数据进行持久化到 xml,并进行状态保存。

?

?

?

?

An interface to a storage mechanism for making dialog settings persistent. The store manages a collection of key/value pairs. The keys must be strings and the values can be either, strings or array of strings. Convenience API to convert primitive types to strings is provided.

?

?

?

?

? ? NewWizard wizard = new NewWizard();

? ? ? ? wizard.setCategoryId(categoryId);

wizard.setWindowTitle(windowTitle);

?

? ? ? ? ISelection selection = workbenchWindow.getSelectionService()

? ? ? ? ? ? ? ? .getSelection();

? ? ? ? IStructuredSelection selectionToPass = StructuredSelection.EMPTY;

? ? ? ? if (selection instanceof IStructuredSelection) {

? ? ? ? ? ? selectionToPass = (IStructuredSelection) selection;

? ? ? ? } else {

? ? ? ? ? ? // @issue the following is resource-specific legacy code

? ? ? ? ? ? // Build the selection from the IFile of the editor

? ? ? ? ? ? Class resourceClass = LegacyResourceSupport.getResourceClass();

? ? ? ? ? ? if (resourceClass != null) {

? ? ? ? ? ? ? ? IWorkbenchPart part = workbenchWindow.getPartService()

? ? ? ? ? ? ? ? ? ? ? ? .getActivePart();

? ? ? ? ? ? ? ? if (part instanceof IEditorPart) {

? ? ? ? ? ? ? ? ? ? IEditorInput input = ((IEditorPart) part).getEditorInput();

? ? ? ? ? ? ? ? ? ? Object resource = Util.getAdapter(input, resourceClass);

? ? ? ? ? ? ? ? ? ? if (resource != null) {

? ? ? ? ? ? ? ? ? ? ? ? selectionToPass = new StructuredSelection(resource);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

?

? ? ? ? wizard.init(workbenchWindow.getWorkbench(), selectionToPass);

?

? ? ? ? IDialogSettings workbenchSettings = WorkbenchPlugin.getDefault()

? ? ? ? ? ? ? ? .getDialogSettings();

? ? ? ? IDialogSettings wizardSettings = workbenchSettings

? ? ? ? ? ? ? ? .getSection("NewWizardAction"); //$NON-NLS-1$

? ? ? ? if (wizardSettings == null) {

wizardSettings = workbenchSettings.addNewSection("NewWizardAction"); //$NON-NLS-1$

}

? ? ? ? wizard.setDialogSettings(wizardSettings);

? ? ? ? wizard.setForcePreviousAndNextButtons(true);

?

? ? ? ? Shell parent = workbenchWindow.getShell();

? ? ? ? WizardDialog dialog = new WizardDialog(parent, wizard);

? ? ? ? dialog.create();

? ? ? ? dialog.getShell().setSize(

? ? ? ? ? ? ? ? Math.max(SIZING_WIZARD_WIDTH, dialog.getShell().getSize().x),

? ? ? ? ? ? ? ? SIZING_WIZARD_HEIGHT);

? ? ? ? PlatformUI.getWorkbench().getHelpSystem().setHelp(dialog.getShell(),

IWorkbenchHelpContextIds.NEW_WIZARD);

? ? ? ? dialog.open();

?

?

这是eclipse 打开一个创建对话框的代码,可以借鉴一下。

这个插件内的很多代码大家都可以在做插件开发中借鉴一下的。

?

所有的IHandler 都是通过

CommandAction ?来包装后执行的。

?

CommandAction ?这里的 源码,看看还是有些启发的。

?

public class CommandAction extends Action {

?

private IHandlerService handlerService = null;

?

private ParameterizedCommand parameterizedCommand = null;

?

private ICommandListener commandListener;

?

protected CommandAction() {

?

}

?

/**

* Creates the action backed by a command. For commands that don't take

* parameters.

*?

* @param serviceLocator

* ? ? ? ? ? ?The service locator that is closest in lifecycle to this

* ? ? ? ? ? ?action.

* @param commandIdIn

* ? ? ? ? ? ?the command id. Must not be <code>null</code>.

*/

public CommandAction(IServiceLocator serviceLocator, String commandIdIn) {

this(serviceLocator, commandIdIn, null);

}

?

/**

* Creates the action backed by a parameterized command. The parameterMap

* must contain only all required parameters, and may contain the optional

* parameters.

*?

* @param serviceLocator

* ? ? ? ? ? ?The service locator that is closest in lifecycle to this

* ? ? ? ? ? ?action.

* @param commandIdIn

* ? ? ? ? ? ?the command id. Must not be <code>null</code>.

* @param parameterMap

* ? ? ? ? ? ?the parameter map. May be <code>null</code>.

*/

public CommandAction(IServiceLocator serviceLocator, String commandIdIn,

Map parameterMap) {

if (commandIdIn == null) {

throw new NullPointerException("commandIdIn must not be null"); //$NON-NLS-1$

}

init(serviceLocator, commandIdIn, parameterMap);

}

?

protected ICommandListener getCommandListener() {

if (commandListener == null) {

commandListener = new ICommandListener() {

public void commandChanged(CommandEvent commandEvent) {

if (commandEvent.isHandledChanged()

|| commandEvent.isEnabledChanged()) {

if (commandEvent.getCommand().isDefined()) {

setEnabled(commandEvent.getCommand().isEnabled());

}

}

}

};

}

return commandListener;

}

?

/**

* Build a command from the executable extension information.

*?

* @param commandService

* ? ? ? ? ? ?to get the Command object

* @param commandId

* ? ? ? ? ? ?the command id for this action

* @param parameterMap

*/

private void createCommand(ICommandService commandService,

String commandId, Map parameterMap) {

Command cmd = commandService.getCommand(commandId);

if (!cmd.isDefined()) {

WorkbenchPlugin.log("Command " + commandId + " is undefined"); //$NON-NLS-1$//$NON-NLS-2$

return;

}

?

if (parameterMap == null) {

parameterizedCommand = new ParameterizedCommand(cmd, null);

return;

}

?

parameterizedCommand = ParameterizedCommand.generateCommand(cmd,

parameterMap);

}

?

public void dispose() {

// not important for command ID, maybe for command though.

handlerService = null;

if (commandListener != null) {

parameterizedCommand.getCommand().removeCommandListener(

commandListener);

commandListener = null;

}

parameterizedCommand = null;

}

?

/*

* (non-Javadoc)

*?

* @see org.eclipse.jface.action.Action#runWithEvent(org.eclipse.swt.widgets.Event)

*/

public void runWithEvent(Event event) {

if (handlerService == null) {

String commandId = (parameterizedCommand == null ? "unknownCommand" //$NON-NLS-1$

: parameterizedCommand.getId());

WorkbenchPlugin.log("Cannot run " + commandId //$NON-NLS-1$

+ " before command action has been initialized"); //$NON-NLS-1$

return;

}

try {

if (parameterizedCommand != null) {

handlerService.executeCommand(parameterizedCommand, event);

}

} catch (Exception e) {

WorkbenchPlugin.log(e);

}

}

?

/*

* (non-Javadoc)

*?

* @see org.eclipse.jface.action.Action#run()

*/

public void run() {

// hopefully this is never called

runWithEvent(null);

}

?

protected void init(IServiceLocator serviceLocator, String commandIdIn,

Map parameterMap) {

if (handlerService != null) {

// already initialized

return;

}

handlerService = (IHandlerService) serviceLocator

.getService(IHandlerService.class);

ICommandService commandService = (ICommandService) serviceLocator

.getService(ICommandService.class);

ICommandImageService commandImageService = (ICommandImageService) serviceLocator

.getService(ICommandImageService.class);

?

createCommand(commandService, commandIdIn, parameterMap);

if (parameterizedCommand != null) {

setId(parameterizedCommand.getId());

setActionDefinitionId(parameterizedCommand.getId());

try {

setText(parameterizedCommand.getName());

} catch (NotDefinedException e) {

// if we get this far it shouldn't be a problem

}

parameterizedCommand.getCommand().addCommandListener(

getCommandListener());

parameterizedCommand.getCommand().setEnabled(

handlerService.getCurrentState());

setEnabled(parameterizedCommand.getCommand().isEnabled());

setImageDescriptor(commandImageService.getImageDescriptor(

commandIdIn, ICommandImageService.TYPE_DEFAULT));

setDisabledImageDescriptor(commandImageService.getImageDescriptor(

commandIdIn, ICommandImageService.TYPE_DISABLED));

setHoverImageDescriptor(commandImageService.getImageDescriptor(

commandIdIn, ICommandImageService.TYPE_HOVER));

}

}

?

protected ParameterizedCommand getParameterizedCommand() {

return parameterizedCommand;

}

?

public String getActionDefinitionId() {

return super.getActionDefinitionId();

}

}

?

?

?还有org.eclipse.ui.internal.WorkbenchWindow ? ?

这个就是我们的rcp 窗口的实现类。

继承 jface?ApplicationWindow 。

?

?

接下来我们研究一下扩展定义的信息eclipse 是在哪里调用里面的信息,并动态的调用代码?

?

?

?

以action 为例?

?

可以在eclipse 作为菜单、工具栏、弹出菜单 有很几个扩展点都可以实现。

?

看eclipse ?是如何使用扩展的配置信息的。

入口肯定在

?

org.eclipse.ui.internal.WorkbenchWindow?

?

?

?

private final void initializeDefaultServices() {

serviceLocator.registerService(IWorkbenchLocationService.class,

new WorkbenchLocationService(IServiceScopes.WINDOW_SCOPE,

getWorkbench(), this, null, null, null, 1));

// added back for legacy reasons

serviceLocator.registerService(IWorkbenchWindow.class, this);

final ActionCommandMappingService mappingService = new ActionCommandMappingService();

serviceLocator.registerService(IActionCommandMappingService.class,

mappingService);

?

final LegacyActionPersistence actionPersistence = new LegacyActionPersistence(

this);

serviceLocator.registerService(LegacyActionPersistence.class,

actionPersistence);

actionPersistence.read(); ?//关键是这行代码。

?

}

这个是初始化方法。

?

?

方法的内容:

?

public final void read() {

clear();

LegacyActionPersistence.super.read();

?

// 创建 extension registry ?

final IExtensionRegistry registry = Platform.getExtensionRegistry();

int actionSetCount = 0;

int editorContributionCount = 0;

int objectContributionCount = 0;

int viewContributionCount = 0;

int viewerContributionCount = 0;

final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];

?

// 1 ? ?actionSets??extension point.

final IConfigurationElement[] actionSetsExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_ACTION_SETS);

for (int i = 0; i < actionSetsExtensionPoint.length; i++) {

final IConfigurationElement element = actionSetsExtensionPoint[i];

final String name = element.getName();

if (TAG_ACTION_SET.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_ACTION_SETS, actionSetCount++);

}

}

?

// 2 ? ? editorActions extension point.

final IConfigurationElement[] editorActionsExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_EDITOR_ACTIONS);

for (int i = 0; i < editorActionsExtensionPoint.length; i++) {

final IConfigurationElement element = editorActionsExtensionPoint[i];

final String name = element.getName();

if (TAG_EDITOR_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_EDITOR_CONTRIBUTIONS, editorContributionCount++);

}

}

?

// ? ? popupMenus extension point.

final IConfigurationElement[] popupMenusExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_POPUP_MENUS);

for (int i = 0; i < popupMenusExtensionPoint.length; i++) {

final IConfigurationElement element = popupMenusExtensionPoint[i];

final String name = element.getName();

? ? ? ? ? ? ? ? ? ? ? ?//3 ?TAG_OBJECT_CONTRIBUTION

if (TAG_OBJECT_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_OBJECT_CONTRIBUTIONS, objectContributionCount++);

? ? ? ? ? ? ? ? ? ???//4 ?TAG_OBJECT_CONTRIBUTION

} else if (TAG_VIEWER_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_VIEWER_CONTRIBUTIONS, viewerContributionCount++);

}

}

?

// 4 ? viewActions extension point.

final IConfigurationElement[] viewActionsExtensionPoint = registry

.getConfigurationElementsFor(EXTENSION_VIEW_ACTIONS);

for (int i = 0; i < viewActionsExtensionPoint.length; i++) {

final IConfigurationElement element = viewActionsExtensionPoint[i];

final String name = element.getName();

if (TAG_VIEW_CONTRIBUTION.equals(name)) {

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_VIEW_CONTRIBUTIONS, viewContributionCount++);

}

}

?

readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],

actionSetCount);

readEditorContributions(

indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],

editorContributionCount);

readObjectContributions(

indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],

objectContributionCount);

readViewContributions(

indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],

viewContributionCount);

readViewerContributions(

indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],

viewerContributionCount);

}

?

?

代码解释:

final IConfigurationElement[][] indexedConfigurationElements = new IConfigurationElement[5][];

这里一共有5中action的定义,所有这里的2维数组 ?的第一个参数为5了。

?

?

addElementToIndexedArray(element, indexedConfigurationElements,

INDEX_ACTION_SETS, actionSetCount++);

把读出来的?IConfigurationElement element ?添加到对应 ?indexedConfigurationElements 二维数组中。

?

然后分别调用

?

readActionSets(indexedConfigurationElements[INDEX_ACTION_SETS],

actionSetCount);

readEditorContributions(

indexedConfigurationElements[INDEX_EDITOR_CONTRIBUTIONS],

editorContributionCount);

readObjectContributions(

indexedConfigurationElements[INDEX_OBJECT_CONTRIBUTIONS],

objectContributionCount);

readViewContributions(

indexedConfigurationElements[INDEX_VIEW_CONTRIBUTIONS],

viewContributionCount);

readViewerContributions(

indexedConfigurationElements[INDEX_VIEWER_CONTRIBUTIONS],

viewerContributionCount);

?

对不同的action进行 初始化。

?

进入readActionSets中。

?

private final void readActionSets(

final IConfigurationElement[] configurationElements,

final int configurationElementCount) {

//?

// this was an even dumber fix than modifying the path

//?

// stupid navigate group

// SGroup nav = menuService.getGroup(STUPID_NAVIGATE);

// if (!nav.isDefined()) {

// nav.define(new SLocation(new SBar(SBar.TYPE_MENU, null)));

// }

// stupid navigate group

?

final List warningsToLog = new ArrayList(1);

?

for (int i = 0; i < configurationElementCount; i++) {

final IConfigurationElement element = configurationElements[i];

?

// Read the action set identifier.

final String id = readRequired(element, ATT_ID, warningsToLog,

"Action sets need an id"); //$NON-NLS-1$

if (id == null) {

continue;

}

?

// Read the label.

final String label = readRequired(element, ATT_LABEL,

warningsToLog, "Actions set need a label", //$NON-NLS-1$

id);

if (label == null) {

continue;

}

?

// Restrict the handler to when the action set is active.

final LegacyActionSetExpression expression = new LegacyActionSetExpression(

id, window);

?

?

// Read all of the child elements.

readActionsAndMenus(element, id,

warningsToLog, expression, null);

// Define the action set.

}

?

logWarnings(

warningsToLog,

"Warnings while parsing the action sets from the 'org.eclipse.ui.actionSets' extension point"); //$NON-NLS-1$

}

?

?

?

最后找到 ??WorkbenchMenuService ? 类中的populateContributionManager ?方法 具体把扩展点的信息?

添加到了 具体的 ?menu中。

藏的好深。。。。

?

?

MenuLocationURI ?这个类是对 menu?[scheme]:[path]?[query] ?的包装。

?

?

从定义扩展点 到 ?对扩展点的 调用 ?中间包装了很多层。 好多都是以service的形式提供的。

?

?

热点排行