HadoopIntellijPlugin插件文件系统配置设计和实现2

  本节具体分析一下插件配置中各个具体的配置项设计和实现,包括HDFS连接配置设置、插件系统一般配置中国际化语言支持和浏览器树展现方式配置。

插件配置起点ProjectSetting

  插件的配置项是以Intellij 工程Project为起点,在IDEA启动加载工程后,初始化并读取配置。工程配置设计整体类图:

工程配置设置ProjectSetting和配置管理ProjectSettingManager

  ProjectSetting由HDFS配置和插件通用配置组成,继承配置集合泛型类CompositeProjectConfiguration。ProjectSettingManager是配置管理类,负责初始化整个配置,是Project级别的插件组件,当加载工程时初始化该类。当加载工程的时候,在初始化插件组件方法initComponent()中调用importDefaultSettings() 方法,判断当前工程文件是否有该插件工程的配置文件,没有,那就创建默认的配置,配置文件名称:hdfsnavigator.xml重写loadState()方法,读取各个配置项,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* 导入新的配置
* @param isNewProject
*/
public void importDefaultSettings(final boolean isNewProject)
{
final Project project = getProject();
Boolean settingsLoaded = project.getUserData(FileSystemDataKeys.PROJECT_SETTINGS_LOADED_KEY);
if ((settingsLoaded == null) || (!settingsLoaded.booleanValue()) || (!isNewProject))
{
String message = LocaleLanguageManager.getInstance().getResourceBundle().getString(LanguageKeyWord.IMPORTDEFAULTSETTINGSASKINFORMATION) +
project.getName() + "\"?";
String strYes=LocaleLanguageManager.getInstance().getResourceBundle().getString(LanguageKeyWord.ASKYES);
String strNo=LocaleLanguageManager.getInstance().getResourceBundle().getString(LanguageKeyWord.ASKNO);
MessageUtil.showQuestionDialog(project, LocaleLanguageManager.getInstance().getResourceBundle().getString(LanguageKeyWord.IMPORTDEFAULTSETTINGSASKTITLE),
message, new String[]{strYes, strNo}, 0, new MessageCallback(Integer.valueOf(0))
{
protected void execute()
{
try
{
Element element = new Element("state");
ProjectSettings defaultProjectSettings = DefaultProjectSettingsManager.getInstance().
getDefaultProjectSettings();
defaultProjectSettings.writeConfiguration(element);
ConnectionBundleSettings.IS_IMPORT_EXPORT_ACTION.set(true);
getProjectSettings().readConfiguration(element);

(EventUtil.notify(project, ConnectionSettingsListener.TOPIC)).connectionsChanged();
if (!isNewProject)
{
MessageUtil.showInfoDialog(project, "Project Settings",
"Default project settings loaded to project \"" + project.getName() + "\".");
}
} finally
{
ConnectionBundleSettings.IS_IMPORT_EXPORT_ACTION.set(false);
}

}
});
}
}
/**
* 读取并解析配置
* @param element
*/
@Override
public void loadState(Element element)
{
projectSettings.readConfiguration(element);
getProject().putUserData(FileSystemDataKeys.PROJECT_SETTINGS_LOADED_KEY, true);
}

HDFS文件系统浏览器通用配置GeneraProjectSetting和UI GeneralProjectSettingsFrom

  这里定义了通用配置的UI界面,和操作管理类,具体的设置分为国际化语言配置和树展现方式,由具体的类和UI去实现。GeneraProjectSetting 通用配置管理类,主要获取语言配置和树展现方式配置,核心代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* 初始化
* @param project
*/
public GeneralProjectSettings(Project project)
{
super(project);
//区域语言设置
regionalSettings = new RegionalSettings();
regionalSettings.setProject(project);
//HDFS文件系统浏览器树展现方式设置
browserSettings = new BrowserSettings();
browserSettings.setProject(project);
}
/**
* 获取语言设置配置
* @return
*/
public RegionalSettings getRegionalSettings()
{
return regionalSettings;
}

/**
* 获取HDFS浏览器树展现方式配置
* @return
*/
public BrowserSettings getBrowserSettings()
{
return browserSettings;
}
/**
* 创建通用配置编辑UI
* @return
*/
public GeneralProjectSettingsForm createConfigurationEditor()
{
return new GeneralProjectSettingsForm(this);
}
/**
* 获取通用配置集合
* @return
*/
protected Configuration[] createConfigurations()
{
return new Configuration[]{regionalSettings,browserSettings};
}

  GeneralProjectSettingsForm 通用配置的UI,比较简单,使用两个Panel,保存语言配置和树的展现方式配置。

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 初始化通用配置UI
* @param generalSettings
*/
public GeneralProjectSettingsForm(GeneralProjectSettings generalSettings)
{
super(generalSettings);
resetFormChanges();
registerComponent(mainPanel);
localeSettingsPanel.add(generalSettings.getRegionalSettings().createComponent(), BorderLayout.CENTER);
browsersettingPanel.add(generalSettings.getBrowserSettings().createComponent(), BorderLayout.CENTER);
}

HDFS连接connection配置

HDFS连接Connection配置设计类图如下:

相关连接配置类讲解

连接配置管理类ConnectionSetting
HDFS连接配置类ConnectionFileSystemSettings
HDFS连接集合配置类ConnectionBundleSettings
ConnectionSettings 是HDFS连接配置的管理类,获取ConnFileSystemSettings 和ConnectionBundleSettings
ConnectionFileSystemSettings抽象类为HDFS连接设置类,包括设置HDFS的Host、端口;MR的Host和端口;HDFS连接的用户等等。
ConnectionBundleSettings抽象类是配置的集合类,增加、删除一个配置等等
ConnectionFileSystemSettings类继承Configuration泛型类,实现了readConfiguration和witreConfiguartion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/**
* 读取配置并解析
* @param element
*/
public void readConfiguration(Element element)
{
String connectionId = getString(element, "id", null);
if (connectionId != null)
{
parent.setConnectionId(connectionId);
}
name = getString(element, "name", name);
description = getString(element, "description", description);
fileSystemType = FileSystemType.get(getString(element, "database-type", fileSystemType.getName()));
databaseVersion = getDouble(element, "database-version", databaseVersion);
user = getString(element, "user", user);
if(StringUtil.isEmptyOrSpaces(user))
{
user=System.getProperty("user.name");
}
password = decodePassword(getString(element, "password", password));
active = getBoolean(element, "active", active);
osAuthentication = getBoolean(element, "os-authentication", osAuthentication);
updateHashCode();
}
/**
* 将设置的配置项写入XML
* @param element
*/
public void writeConfiguration(Element element)
{
setString(element, "name", nvl(name));
setString(element, "description", nvl(description));
setBoolean(element, "active", active);
setBoolean(element, "os-authentication", osAuthentication);
setString(element, "database-type", nvl(fileSystemType == null ? FileSystemType.UNKNOWN.getName() : fileSystemType.getName()));
setDouble(element, "database-version", databaseVersion);
setString(element, "user", nvl(user));
setString(element, "password", encodePassword(password));
}

  ConnectionBundleSettings HDFS 连接集合类,继承ProjectConfiguration泛型类,并且也实现了readConfiguartion 和WriteConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* 读取配置并解析
* @param element
*/
public void readConfiguration(Element element)
{
if (IS_IMPORT_EXPORT_ACTION.get())
{
Project project = getProject();
List<ConnectionHandler> connectionHandlers = connectionBundle.getAllConnectionHandlers();
ConnectionManager.getInstance(project).disposeConnections(connectionHandlers);
}
for (Object o : element.getChildren())
{
Element connectionElement = (Element) o;
String connectionId = connectionElement.getAttributeValue("id");
ConnectionHandler connectionHandler = null;
if (connectionId != null)
{
connectionHandler = connectionBundle.getConnection(connectionId);
}
if (connectionHandler == null)
{
//创建一个ConnectionHandler
ConnectionSettings connectionSettings = new ConnectionSettings(this);
connectionSettings.readConfiguration(connectionElement);
connectionHandler = new ConnectionHandlerImpl(connectionBundle, connectionSettings);
connectionBundle.addConnection(connectionHandler);
} else
{
ConnectionSettings connectionSettings = connectionHandler.getSettings();
connectionSettings.readConfiguration(connectionElement);
}
}
}
/**
* 写入配置XML
* @param element
*/
public void writeConfiguration(Element element)
{
for (ConnectionHandler connectionHandler : connectionBundle.getConnectionHandlers().getFullList())
{
Element connectionElement = new Element("fsconnection");
ConnectionSettings connectionSettings = connectionHandler.getSettings();
connectionSettings.writeConfiguration(connectionElement);
element.addContent(connectionElement);
}
}

界面配置的UI类

配置的UI类主要包括 ConnectionSettingForm、ConnectionBundleSettingsForm、GeneralFileSystemSettingsForm
ConnectionSettingForm HDFS连接配置的主界面UI,使用Tab列表的方式展示需要设置的连接配置
ConnectionBundleSettingsForm 连接集合主界面UI,创建一个连接,就添加到UI集合中显示,可以设置多个HDFS连接
GeneralFileSystemSettingsForm,每个连接的具体设置,包括HDFS的主机地址和端口、MR的地址和端口、访问HDFS的用户名称
这里就不再贴代码了。

国际化多语言和文件浏览器树展现方式设置

国际化多语言设置配置 RegionSettings和RegionalSettingEditorForm

  RegionSettings 语言设置管理类,获取设置的当前UI的语言。RegionalSettingEditorForm 语言设置的UI,很简单,界面上只有一个下拉列表,选中UI需要展示的语言。
RegionSettings类的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
* 定义国际化语言设置类
* Created by fangyuzhong on 17-8-1.
*/
public class RegionalSettings extends Configuration<RegionalSettingsEditorForm>
{
private Locale locale = Locale.getDefault();
private Project project=null;
public void setProject(Project project)
{
this.project = project;
}
/**
* 获取国际化语言配置实例对象
* @param project
* @return
*/
public static RegionalSettings getInstance(Project project)
{
return GeneralProjectSettings.getInstance(project).getRegionalSettings();
}
/**
* 应用
* @throws ConfigurationException
*/
@Override
public void apply() throws ConfigurationException
{
super.apply();

}
/**
* 获取当前配置的语言对象
* @return
*/
public Locale getLocale()
{
return locale;
}
/**
* 设置当前国际化语言
* @param locale
*/
public void setLocale(Locale locale)
{
this.locale = locale;
}
/*********************************************************
* Configuration *
*********************************************************/
/**
* 实例化国际化设置UI
* @return
*/
public RegionalSettingsEditorForm createConfigurationEditor()
{
return new RegionalSettingsEditorForm(this);
}
@Override
public String getConfigElementName()
{
return "regional-settings";
}
/**
* 读取配置,获取当前设置的国际化语言
* @param element
*/
public void readConfiguration(Element element)
{
String localeString = SettingsUtil.getString(element, "locale", Locale.getDefault().toString());
boolean useSystemLocale = localeString.equals("SYSTEM_DEFAULT");
if (useSystemLocale)
{
this.locale = Locale.getDefault();
} else
{
this.locale = LocaleOption.getLocalOption(localeString).getLocale();
}
LocaleLanguageManager.getInstance().setResourceBundle(locale);
}
/**
* 将当前的国际化配置写入配置文件
* @param element
*/
public void writeConfiguration(Element element)
{
String localLanguage ="SYSTEM_DEFAULT";
if(locale!=null)
{
localLanguage = locale.getLanguage()+"-"+locale.getCountry();
}
SettingsUtil.setString(element, "locale", localLanguage);
}
}

HDFS文件系统浏览器树的展现方式设置

  HDFS文件系统浏览器树有两种展现方式可设置,一是以单棵树多根节点展现多个连接,另一个是以Tab列表方式展现多个连接,两种方式界面比较:

  BrowserSettings 树展现方式管理类,获取配置设置的展现方式对象BrowserDisplayMode;BrowserSettingEditorFrom ,设置展示方式的UI。两个类都比较简单,这里就不再说了。