diff --git a/.github/workflows/SonarCloud.yml b/.github/workflows/SonarCloud.yml index 96081e4..22c626f 100644 --- a/.github/workflows/SonarCloud.yml +++ b/.github/workflows/SonarCloud.yml @@ -14,16 +14,16 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: fetch-depth: '' - run: | git fetch --prune --unshallow - - name: Set up JDK 11 + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 - name: Download and install Libs env: @@ -42,7 +42,7 @@ jobs: run: > cd clusterAdminLibrary - mvn -B verify sonar:sonar + mvn -B verify -DskipTests sonar:sonar -Dsonar.projectKey=YanSergey_OneS_ClusterAdmin -Dsonar.projectName="OneS ClusterAdmin" -Dsonar.organization=yansergey diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 1b41e8a..a522c27 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up JDK 11 uses: actions/setup-java@v1 diff --git a/.github/workflows/build-macOS.yml b/.github/workflows/build-macOS.yml index e514b97..7170aad 100644 --- a/.github/workflows/build-macOS.yml +++ b/.github/workflows/build-macOS.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up JDK 11 uses: actions/setup-java@v1 diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d48c70a..38cb664 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Set up JDK 11 uses: actions/setup-java@v1 diff --git a/README.md b/README.md index e33fbdd..505f878 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ ## Утилита для интерактивного администрирования серверов 1С +![Donate](/clusterAdminLibrary/src/main/resources/icons/Rouble.png) +Поддержать проект https://boosty.to/YanSergeyCoder + Статья с описанием возможностей утилиты на Infostart https://infostart.ru/public/1489055/ Разработка ведется в `Eclipse IDE for Java Developers` diff --git a/clusterAdminApplication/pom.xml b/clusterAdminApplication/pom.xml index 6d61176..36546db 100644 --- a/clusterAdminApplication/pom.xml +++ b/clusterAdminApplication/pom.xml @@ -6,7 +6,7 @@ ru.yanygin ru.yanygin.clusterAdminApplication - 0.3.0 + 0.4.0 jar @@ -86,20 +86,20 @@ org.slf4j slf4j-api - 1.7.30 + 2.0.13 ch.qos.logback logback-classic - 1.2.3 + 1.5.6 ch.qos.logback logback-core - 1.2.3 + 1.5.6 @@ -107,21 +107,21 @@ org.eclipse.platform ${swt.artifactId} - 3.116.0 + 3.120.0 org.eclipse.platform org.eclipse.jface - 3.22.0 + 3.22.100 com.google.code.gson gson - 2.8.6 + 2.10.1 diff --git a/clusterAdminApplication/scripts/echo_fast.bat b/clusterAdminApplication/scripts/echo_fast.bat new file mode 100644 index 0000000..49eeac1 --- /dev/null +++ b/clusterAdminApplication/scripts/echo_fast.bat @@ -0,0 +1,10 @@ +# пока что каждый командный файл должен содержать строку chcp 65001 + +@echo off +chcp 65001 +echo server: %v8serverName%:%v8managerPort% +echo password: %v8password% +echo infobase: %v8infobase% +echo username: %v8username% +echo infobase1: %infobase1% +echo end diff --git a/clusterAdminApplication/scripts/echo_long.bat b/clusterAdminApplication/scripts/echo_long.bat new file mode 100644 index 0000000..4e2a565 --- /dev/null +++ b/clusterAdminApplication/scripts/echo_long.bat @@ -0,0 +1,9 @@ +# пока что каждый командный файл должен содержать строку chcp 65001 + +@echo off +chcp 65001 +#chcp +ping 127.0.0.1 -n 20 +echo server: %v8serverName%:%v8managerPort% +echo infobase: %v8infobase% +echo end diff --git "a/clusterAdminApplication/scripts/\320\222\321\213\320\263\321\200\321\203\320\267\320\272\320\260_CF.bat" "b/clusterAdminApplication/scripts/\320\222\321\213\320\263\321\200\321\203\320\267\320\272\320\260_CF.bat" new file mode 100644 index 0000000..56e233d --- /dev/null +++ "b/clusterAdminApplication/scripts/\320\222\321\213\320\263\321\200\321\203\320\267\320\272\320\260_CF.bat" @@ -0,0 +1,2 @@ +chcp 65001 +"C:\Program Files\1cv8\common\1cestart.exe" DESIGNER /S %v8serverName%:%v8managerPort%\%v8infobase% /N Администратор /P 1234 /DumpCfg D:\DumpIB\%v8infobase%.cf \ No newline at end of file diff --git "a/clusterAdminApplication/scripts/\320\222\321\213\320\263\321\200\321\203\320\267\320\272\320\260_DT.bat" "b/clusterAdminApplication/scripts/\320\222\321\213\320\263\321\200\321\203\320\267\320\272\320\260_DT.bat" new file mode 100644 index 0000000..9ae7f40 --- /dev/null +++ "b/clusterAdminApplication/scripts/\320\222\321\213\320\263\321\200\321\203\320\267\320\272\320\260_DT.bat" @@ -0,0 +1,2 @@ +chcp 65001 +"C:\Program Files\1cv8\common\1cestart.exe" DESIGNER /S %v8serverName%:%v8managerPort%\%v8infobase% /N Администратор /P 1234 /DumpIB D:\DumpIB\%v8infobase%.dt \ No newline at end of file diff --git "a/clusterAdminApplication/scripts/\320\227\320\260\320\277\321\203\321\201\320\272_\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200.bat" "b/clusterAdminApplication/scripts/\320\227\320\260\320\277\321\203\321\201\320\272_\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200.bat" new file mode 100644 index 0000000..1f0079d --- /dev/null +++ "b/clusterAdminApplication/scripts/\320\227\320\260\320\277\321\203\321\201\320\272_\320\232\320\276\320\275\321\204\320\270\320\263\321\203\321\200\320\260\321\202\320\276\321\200.bat" @@ -0,0 +1,2 @@ +chcp 65001 +"C:\Program Files\1cv8\common\1cestart.exe" DESIGNER /S %v8serverName%:%v8managerPort%\%v8infobase% /N Администратор /P 1234 \ No newline at end of file diff --git "a/clusterAdminApplication/scripts/\320\227\320\260\320\277\321\203\321\201\320\272_\320\237\321\200\320\265\320\264\320\277\321\200\320\270\321\217\321\202\320\270\320\265.bat" "b/clusterAdminApplication/scripts/\320\227\320\260\320\277\321\203\321\201\320\272_\320\237\321\200\320\265\320\264\320\277\321\200\320\270\321\217\321\202\320\270\320\265.bat" new file mode 100644 index 0000000..d52a921 --- /dev/null +++ "b/clusterAdminApplication/scripts/\320\227\320\260\320\277\321\203\321\201\320\272_\320\237\321\200\320\265\320\264\320\277\321\200\320\270\321\217\321\202\320\270\320\265.bat" @@ -0,0 +1,2 @@ +chcp 65001 +"C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /S %v8serverName%:%v8managerPort%\%v8infobase% /N Администратор /P 1234 \ No newline at end of file diff --git a/clusterAdminLibrary/.settings/org.eclipse.m2e.core.prefs b/clusterAdminLibrary/.settings/org.eclipse.m2e.core.prefs index f897a7f..32680bc 100644 --- a/clusterAdminLibrary/.settings/org.eclipse.m2e.core.prefs +++ b/clusterAdminLibrary/.settings/org.eclipse.m2e.core.prefs @@ -1,4 +1,4 @@ -activeProfiles= +activeProfiles=windows-x86_64 eclipse.preferences.version=1 resolveWorkspaceProjects=true version=1 diff --git a/clusterAdminLibrary/pom.xml b/clusterAdminLibrary/pom.xml index 9b918db..11a9b87 100644 --- a/clusterAdminLibrary/pom.xml +++ b/clusterAdminLibrary/pom.xml @@ -6,7 +6,7 @@ ru.yanygin ${artifactId} - 0.3.0-SNAPSHOT + 0.4.0-SNAPSHOT jar @@ -87,21 +87,21 @@ org.eclipse.platform ${swt.artifactId} - 3.116.0 + 3.120.0 org.eclipse.platform org.eclipse.swt - 3.116.0 + 3.120.0 org.junit.jupiter junit-jupiter-api - 5.8.2 + 5.10.2 test @@ -109,28 +109,29 @@ org.slf4j slf4j-api - 1.7.30 + 2.0.13 - + ch.qos.logback logback-classic - 1.2.3 + 1.5.6 + ch.qos.logback logback-core - 1.2.3 + 1.5.6 org.eclipse.platform org.eclipse.core.commands - 3.9.800 + 3.10.400 @@ -169,7 +170,7 @@ com.google.code.gson gson - 2.8.2 + 2.10.1 @@ -215,14 +216,14 @@ org.apache.maven maven-model - 3.8.5 + 3.9.6 org.json json - 20220320 + 20240303 diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/AssignmentRuleContentProvider.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/AssignmentRuleContentProvider.java new file mode 100644 index 0000000..9aaa7f7 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/AssignmentRuleContentProvider.java @@ -0,0 +1,34 @@ +package ru.yanygin.clusterAdminLibrary; + +import com._1c.v8.ibis.admin.IAssignmentRuleInfo; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.eclipse.jface.viewers.IStructuredContentProvider; + +/** Контент-провайдер для заполнения таблицы с ТНФ. */ +public class AssignmentRuleContentProvider implements IStructuredContentProvider { + + static Map ruleNumbers = new HashMap<>(); + + /** + * Returns the elements in the input, which must be either an array or a Collection . + */ + @Override + public Object[] getElements(Object inputElement) { + List listTnf = (List) inputElement; + setRuleNumbers(listTnf); + return listTnf.toArray(); + } + + private static void setRuleNumbers(List rules) { + ruleNumbers.clear(); + for (int i = 0; i < rules.size(); i++) { + ruleNumbers.put(rules.get(i), i + 1); + } + } + + public static int getRuleNumber(IAssignmentRuleInfo rule) { + return ruleNumbers.getOrDefault(rule, 0); + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/AssignmentRuleLabelProvider.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/AssignmentRuleLabelProvider.java new file mode 100644 index 0000000..86d0d35 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/AssignmentRuleLabelProvider.java @@ -0,0 +1,188 @@ +package ru.yanygin.clusterAdminLibrary; + +import com._1c.v8.ibis.admin.IAssignmentRuleInfo; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import org.eclipse.jface.viewers.ColumnLabelProvider; + +/** Провайдер требований назначения функциональности. */ +public class AssignmentRuleLabelProvider extends ColumnLabelProvider { + + private static final String NUMBER = "AssignmentRule.Number"; + private static final String OBJECT_TYPE = "AssignmentRule.ObjectType"; + private static final String RULE_TYPE = "AssignmentRule.RuleType"; + private static final String INFOBASE_NAME = "AssignmentRule.InfoBaseName"; + private static final String APPLICATION_EXT = "AssignmentRule.ApplicationExt"; + private static final String PRIORITY = "AssignmentRule.Priority"; + + private static Config commonConfig = Config.currentConfig; + private static ColumnProperties columnProperties = + commonConfig.getColumnsProperties(IAssignmentRuleInfo.class); + + private String columnName; + + public static final String RULE_TYPE_DO_NOT_ASSIGN = + Messages.getString("AssignmentRule.RuleType.DoNotAssign"); // "Не назначать" = 0 + public static final String RULE_TYPE_AUTO = + Messages.getString("AssignmentRule.RuleType.Auto"); // "Авто" = 1 + public static final String RULE_TYPE_ASSIGN = + Messages.getString("AssignmentRule.RuleType.Assign"); // "Назначать" = 2 + + static final String[] ruleType = {RULE_TYPE_DO_NOT_ASSIGN, RULE_TYPE_AUTO, RULE_TYPE_ASSIGN}; + static final Map objectTypes = fillObjectType(); + + public AssignmentRuleLabelProvider(String columnName) { + this.columnName = columnName; + } + + private static Map fillObjectType() { + + Map objectTypes = new HashMap<>(); + objectTypes.put("", Messages.getString("AssignmentRule.ObjectType.ForAll")); + + String[] ruleKeys = { + "Connection", + "ClientTestingService", + "SessionDataService", + "DataEditLockService", + "JobService", + "ExternalDataSourceXMLAService", + "ExternalSessionManagerService", + "EventLogService", + "TimestampService", + "AuxiliaryService", + "ExternalDataSourceODBCService", + "OpenID2ProviderContextService", + "SessionReuseService", + "TransactionLockService", + "LicenseService", + "FulltextSearchService", + "SettingsService", + "NumerationService", + "DataBaseConfigurationUpdateService", + "DatabaseTableNumberingService", + "CounterService", + + // доступны с версии платформы, где добавлен дата акселератор (?) + "DbCopiesTimeService", + "GetSessionsService", + "IntegrationDataService", + "DbCopiesService", + "DataAcceleratorService" + }; + Arrays.sort(ruleKeys); + + for (String ruleKey : ruleKeys) { + objectTypes.put(ruleKey, Messages.getString("AssignmentRule.ObjectType." + ruleKey)); + } + return objectTypes; + } + + /** Возвращает возможные значения доп. параметров. */ + public static String[] getApplicationExtValues() { + String[] appExtValues = { + "Designer", + "1CV8", + "1CV8C", + "1CV8CDirect", + "WebClient", + "COMConnection", + "WSConnection", + "HTTPServiceConnection", + "ODataConnection", + "BotConnection", + "WebServerExtension", + "MobileClient", + "AnalyticsSystemClient", + "AnalyticsSystemQuery", + "BackgroundJob.ScheduledJob.<Имя объекта конфигурации>", + "BackgroundJob.CommonModule", + "BackgroundJob.CommonModule.<Имя модуля>.<Имя метода>", + "BackgroundJob.FullTextSearchIndexUpdate", + "BackgroundJob.GenerateReport.<Полное имя объекта конфигурации>", + "BackgroundJob.InputByString.<Полное имя объекта конфигурации>", + "BackgroundJob.DynamicListSearch.<Полное имя формы>.<Имя таблицы формы связанной со списком>", + "BackgroundJob.DBCopiesFilling", + "BackgroundJob.DBCopiesNotification", + "BackgroundJob.UpdateDataHistoryImmediatelyAfterWrite", + "BackgroundJob.AfterWriteDataHistoryVersionsProcessing", + "BackgroundJob.GlobalSearchFunctionsMenu", + "BackgroundJob.GlobalSearchFullTextSearch", + "BackgroundJob.GlobalSearchHelp", + "BackgroundJob.GlobalSearchAllFunctions", + "BackgroundJob.GlobalSearch.<имя модуля>.<имя метода>", + "BackgroundJob.IntegrationServiceReceivedMessagesProcessing.<Полное имя канала сервиса интеграции>", + "SystemBackgroundJob.DBConfigUpdate", + "SystemBackgroundJob.RecalcTotals", + "BackgroundJob.SendIntegrationSystemMessagesQueueProcessing.<полное имя сервиса интеграции>", + "BackgroundJob.ReceiveIntegrationSystemMessagesQueueProcessing.<полное имя сервиса интеграции>", + "BackgroundJob.ReceivingIntegrationSystemMessages.<полное имя сервиса интеграции>", + "BackgroundJob.ReceivedIntegrationSystemMessagesProcessing.<полное имя канала сервиса интеграции>", + "BackgroundJob.StandaloneExchange" + }; + return appExtValues; + } + + private static void putObjectType(Map objectTypes, String key) { + objectTypes.put(key, Messages.getString("AssignmentRule.ObjectType." + key)); + } + + public static Map getObjectTypes() { + return objectTypes; + } + + public static String getObjectType(String key) { + return objectTypes.getOrDefault(key, "unknown"); + } + + @Override + public String getText(Object element) { + if (!(element instanceof IAssignmentRuleInfo)) { + return null; + } + return String.valueOf(getValue(element)); + } + + /** + * Возвращает наименование правила ТНФ. + * + * @param element - элемент, для которого нужно вернуть наименование ТНФ + */ + public Object getValue(Object element) { + if (!(element instanceof IAssignmentRuleInfo)) { + return null; + } + IAssignmentRuleInfo rule = (IAssignmentRuleInfo) element; + + switch (columnName) { + case NUMBER: + return AssignmentRuleContentProvider.getRuleNumber(rule); + case OBJECT_TYPE: + return objectTypes.getOrDefault(rule.getObjectType(), "unknown"); + case RULE_TYPE: + return ruleType[rule.getRuleType()]; + case INFOBASE_NAME: + return rule.getInfoBaseName(); + case APPLICATION_EXT: + return rule.getApplicationExt(); + case PRIORITY: + return rule.getPriority(); + default: + return "UnknownColumn"; + } + } + + /** Инициализация имен колонок. */ + protected static void initColumnsName() { + columnProperties.addColumnsInMap( + OBJECT_TYPE, RULE_TYPE, INFOBASE_NAME, APPLICATION_EXT, NUMBER, PRIORITY); + } + + private static class Strings { + + static String getString(String key) { + return Messages.getString("AssignmentRule." + key); // $NON-NLS-1$ + } + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BackgroundTask.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BackgroundTask.java new file mode 100644 index 0000000..8ae2316 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BackgroundTask.java @@ -0,0 +1,468 @@ +package ru.yanygin.clusterAdminLibrary; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.swt.widgets.TableItem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** Фоновый процесс. */ +public class BackgroundTask { + + static final Logger LOGGER = LoggerFactory.getLogger(BackgroundTask.class.getSimpleName()); + + static final String starterPath = "\"C:\\Program Files\\1cv8\\%v8version%\\bin\\1cv8.exe\""; + static final String designerCommand = "DESIGNER"; + static final String enterpriseCommand = "ENTERPRISE"; + static final String infobasePath = "/S%v8serverName%:%v8managerPort%\\%v8infobase%"; + static final String logonCommand = "/N%v8username% /P%v8password%"; + static final String FILEPATH_PARAM_KEY = "%v8FilePath%"; + + static int countOfRunning = 0; + static int countOfCompleted = 0; + static int countWithError = 0; + static Map taskNamesCounter = new HashMap<>(); + + static Image taskRunning = Helper.getImage("taskRunning.png"); //$NON-NLS-1$ + static Image taskCompleted = Helper.getImage("taskCompleted.png"); //$NON-NLS-1$ + static Image taskError = Helper.getImage("taskError.png"); //$NON-NLS-1$ + + File script; + String scriptText; + String v8Command; + String fileExtension; + + String scriptName; + + String taskName; + Map params; + + Process scriptProcess; + String processOutput = ""; //$NON-NLS-1$ + int exitCode; + + TaskState state; + TaskState stateLast; + + TaskVariant taskVariant; + V8ActionVariant v8ActionVariant; + + enum TaskState { + RUNNUNG, + DONE, + ERROR + } + + enum TaskVariant { + USER_SCRIPT, + V8ACTION + } + + public enum V8ActionVariant { + RUN_DESIGNER, + RUN_ENTERPRISE, + LOAD_CF, + DUMP_CF, + LOAD_DT, + DUMP_DT + } + + Thread thread; + + Date startDate; + Date finishDate; + + /** + * Инициализация задачи. + * + * @param script - файл скрипта + */ + public BackgroundTask(File script) { + this.taskVariant = TaskVariant.USER_SCRIPT; + + this.script = script; + + try { + this.scriptText = Files.readString(Path.of(script.getPath())); + } catch (IOException excp) { + LOGGER.error( + "Error read script {}", //$NON-NLS-1$ + script.getName(), + excp); + } + + this.scriptName = script.getName(); + } + + /** + * Инициализация задачи. + * + * @param v8ActionVariant - Вариант команды 1С + */ + public BackgroundTask(V8ActionVariant v8ActionVariant) { + this.taskVariant = TaskVariant.V8ACTION; + this.v8ActionVariant = v8ActionVariant; + + final String launchMode; + if (v8ActionVariant == V8ActionVariant.RUN_ENTERPRISE) { + launchMode = enterpriseCommand; + } else { + launchMode = designerCommand; + } + + final String v8Command; + switch (v8ActionVariant) { + case DUMP_CF: + this.fileExtension = ".cf"; + v8Command = String.join(" ", "/DumpCfg", FILEPATH_PARAM_KEY); + break; + case LOAD_CF: + this.fileExtension = ".cf"; + v8Command = String.join(" ", "/LoadCfg", FILEPATH_PARAM_KEY); + break; + case DUMP_DT: + this.fileExtension = ".dt"; + v8Command = String.join(" ", "/DumpIB", FILEPATH_PARAM_KEY); + break; + case LOAD_DT: + this.fileExtension = ".dt"; + v8Command = String.join(" ", "/RestoreIB", FILEPATH_PARAM_KEY); + break; + default: + v8Command = ""; + break; + } + + boolean logonEnabled = Config.currentConfig.getRequestLogon(); + + this.scriptText = + String.join( + " ", + starterPath, + launchMode, + infobasePath, + logonEnabled ? logonCommand : "", + v8Command); + + this.scriptName = v8ActionVariant.toString(); + } + + private void generateTaskName() { + + int taskNumber = taskNamesCounter.getOrDefault(scriptName, 0); + taskNumber++; + taskNamesCounter.put(scriptName, taskNumber); + + if (taskVariant == TaskVariant.USER_SCRIPT) { + this.taskName = String.format("%s (#%d)", scriptName, taskNumber); + } else { + this.taskName = + String.format( + "%s %s:%s/%s (#%d)", + scriptName, + params.get("v8serverName"), + params.get("v8managerPort"), + params.get("v8infobase"), + taskNumber); + } + } + + /** Получить текст скрипта. */ + public String getScriptText() { + return this.scriptText; + } + + /** Получить имя скрипта. */ + public String getScriptName() { + return this.scriptName; + } + + /** Определяет, я вляется ли параметр путем к файлу. */ + public boolean isFilepathParam(String paramName) { + return FILEPATH_PARAM_KEY.contains(paramName); + } + + /** Получить строку для фильтра выбора файла. */ + public String getFilenameFilterExt() { + return "*".concat(fileExtension); + } + + /** Определяет поведение диалога выбора файла (сохранение или открытие). */ + public boolean isSaveCommand() { + return v8ActionVariant == V8ActionVariant.DUMP_CF || v8ActionVariant == V8ActionVariant.DUMP_DT; + } + + /** + * Установка параметров задачи. + * + * @param params - Параметры задачи + */ + public void setParams(Map params) { + this.params = params; + generateTaskName(); + } + + /** + * Получить количество запущенных заданий. + * + * @return количество запущенных задач + */ + public static int getRunningCount() { + return countOfRunning; + } + + /** + * Установить количество запущенных заданий. + * + * @param count - количество + */ + public static void setCount(int count) { + countOfRunning = count; + } + + /** Сбросить в 0 посчитанное количество заданий. */ + public static void resetCount() { + countOfRunning = 0; + countOfCompleted = 0; + countWithError = 0; + } + + /** + * Считает количество запущенных/завершенных заданий. + * + * @param task - задача + */ + private static void calculateCount(BackgroundTask task) { + + if (task.isRunning()) { + countOfRunning++; + } else if (task.exitCode != 0) { + countWithError++; + } else { + countOfCompleted++; + } + } + + /** + * Устанавливает заголовок вкладки с задачами в зависимости от количества запущенных/завершенных + * заданий. + * + * @param tab - вкладка с задачами + */ + public static void setTabTitle(TabItem tab) { + + String title = + String.format( + "Tasks (Run: %d, Completed: %d, Error: %d)", + countOfRunning, countOfCompleted, countWithError); + + // countWithError == 0 + // ? String.format("Tasks (Run: %d, Completed: %d)", countOfRunning, + // countOfCompleted) + // : String.format( + // "Tasks (Run: %d, Completed: %d, Error: %d)", + // countOfRunning, countOfCompleted, countWithError); + + tab.setText(title); + tab.setImage(countOfRunning == 0 ? taskCompleted : taskRunning); + } + + /** + * Получить имя задания. + * + * @return name of task + */ + public String getTaskName() { + return taskName; + } + + /** + * Получить описание задания для вывода в списке. + * + * @return описание задания для вывода в списке + */ + public String[] getDescription() { + String stateString = ""; + + switch (state) { + case DONE: + stateString = "done"; + break; + case ERROR: + stateString = "error"; + break; + case RUNNUNG: + default: + stateString = "run"; + break; + } + + // String paramsAsString = + // params.keySet().stream() + // .map(key -> key + " = " + params.get(key)) + // .collect(Collectors.joining("\n")); + + return new String[] { + taskName, + stateString, + Helper.dateToString(startDate), + Helper.dateToString(finishDate), + params.toString() + }; + } + + /** + * Задание запущено. + * + * @return true если задание еще запущено + */ + public boolean isRunning() { + return state == TaskState.RUNNUNG; + } + + /** + * Получить лог выполнения задачи. + * + * @return лог выполнения задачи + */ + public String getLog() { + return processOutput; + } + + /** + * Получить иконку задачи. + * + * @return Иконка визуализирующая текущее состояние задачи + */ + public Image getIcon() { + + switch (state) { + case DONE: + return taskCompleted; + case ERROR: + return taskError; + case RUNNUNG: + default: + return taskRunning; + } + } + + /** + * Получить дату начала выполнения задания. + * + * @return дата начала выполнения задания + */ + public Date getStartDate() { + return startDate; + } + + /** + * Получить дату завершения задания. + * + * @return дата нзавершения задания + */ + public Date getFinishDate() { + return finishDate; + } + + /** + * Оновить состояние задания. + * + * @param tableItem - элемент таблицы содержащий объект задания + */ + public void update(TableItem tableItem) { + if (state != stateLast) { // обновляем только при изменении состояния + tableItem.setText(this.getDescription()); + tableItem.setImage(this.getIcon()); + stateLast = state; + } + + calculateCount(this); + } + + /** Запуск фонового задания. */ + public void run() { + + thread = + new Thread( + () -> { + startDate = new Date(); + + ProcessBuilder processBuilder = new ProcessBuilder(); + // "cmd.exe", //$NON-NLS-1$ + // "/c", //$NON-NLS-1$ + // "chcp", //$NON-NLS-1$ + // "65001", //$NON-NLS-1$ + // script.getAbsolutePath() + // ).inheritIO(); + // processBuilder.command(script.getAbsolutePath()); + + String currentCommand = + taskVariant == TaskVariant.USER_SCRIPT ? script.getAbsolutePath() : scriptText; + + processBuilder.command( + "cmd.exe", //$NON-NLS-1$ + "/c", //$NON-NLS-1$ + currentCommand); // script.getAbsolutePath()); + + Map env = processBuilder.environment(); + params.forEach(env::put); + + try { + scriptProcess = processBuilder.start(); + } catch (Exception excp) { + LOGGER.error("Error launch user script <{}>", scriptName); //$NON-NLS-1$ + LOGGER.error("\t<{}>", processOutput, excp); //$NON-NLS-1$ + Helper.showMessageBox(excp.getLocalizedMessage()); + return; + } + state = TaskState.RUNNUNG; + + LOGGER.debug("Script process runnung = {}", scriptProcess.isAlive()); //$NON-NLS-1$ + LOGGER.debug("Script process parent CMD pid={}", scriptProcess.pid()); //$NON-NLS-1$ + Stream subprocesses = scriptProcess.children(); + subprocesses.forEach( + subprocess -> + LOGGER.debug( + "\tsubprocess -> {}, pid={}", //$NON-NLS-1$ + subprocess.info().command().get(), + subprocess.pid())); + + // Читаем вывод скрипта + try { + BufferedReader reader = + new BufferedReader( + new InputStreamReader( + scriptProcess.getInputStream(), + // "cp866")); // windows-1251, cp866, UTF-8 + StandardCharsets.UTF_8)); + + String line; + while ((line = reader.readLine()) != null) { + processOutput = processOutput.concat(System.lineSeparator()).concat(line); + } + + exitCode = scriptProcess.waitFor(); + + } catch (InterruptedException | IOException excp) { + LOGGER.error("Error: ", excp); //$NON-NLS-1$ + } + + state = exitCode == 0 ? TaskState.DONE : TaskState.ERROR; + finishDate = new Date(); + }); + + thread.start(); + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BaseInfoExtended.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BaseInfoExtended.java index 64ed60e..0bb9a32 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BaseInfoExtended.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/BaseInfoExtended.java @@ -174,6 +174,9 @@ public int compareTo(BaseInfoExtended o) { break; case DATE: + compareResult = ((Date) left).compareTo((Date) right); + break; + case TEXT: default: compareResult = @@ -242,6 +245,7 @@ public static void init() { LockInfoExtended.initColumnsName(); WorkingProcessInfoExtended.initColumnsName(); WorkingServerInfoExtended.initColumnsName(); + AssignmentRuleLabelProvider.initColumnsName(); } /** diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/CellValue.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/CellValue.java index 6ab9d76..a17a843 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/CellValue.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/CellValue.java @@ -1,8 +1,6 @@ package ru.yanygin.clusterAdminLibrary; -import java.text.DateFormat; import java.text.DecimalFormat; -import java.text.SimpleDateFormat; import java.util.Date; /** Value of cell from lists. */ @@ -60,7 +58,7 @@ public CellValue(String name, String descr, Object value, CELL_VALUE_TYPE type) break; case DATE: - this.value = dateToString((Date) value); + this.value = Helper.dateToString((Date) value); break; case SECONDS_INT: @@ -100,20 +98,6 @@ public CellValue(String name, String descr, Object value, CELL_VALUE_TYPE type) } } - /** - * Cast date to string. - * - * @param date - date - * @return date format to string - */ - private String dateToString(Date date) { - - DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); //$NON-NLS-1$ - Date emptyDate = new Date(0); - - return date.equals(emptyDate) ? "" : dateFormat.format(date); //$NON-NLS-1$ - } - /** * Cast double value to string. * diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Config.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Config.java index 6e93885..bf248e8 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Config.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Config.java @@ -1,5 +1,6 @@ package ru.yanygin.clusterAdminLibrary; +import com._1c.v8.ibis.admin.IAssignmentRuleInfo; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonIOException; @@ -20,7 +21,10 @@ import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -34,7 +38,8 @@ import org.eclipse.swt.widgets.Shell; import org.json.JSONArray; import org.json.JSONObject; -import org.slf4j.Logger; +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; import org.slf4j.LoggerFactory; import ru.yanygin.clusterAdminLibrary.ColumnProperties.RowSortDirection; import ru.yanygin.clusterAdminLibrary.InfoBaseInfoShortExt.InfobasesSortDirection; @@ -122,10 +127,38 @@ public class Config { @Expose private InfobasesSortDirection infobasesSortDirection = InfobasesSortDirection.DISABLE; + @SerializedName("ListRefreshRate") + @Expose + private int listRefreshRate = 5000; + + @SerializedName("LoggerLevel") + @Expose + private String loggerLevel = "error"; + + @SerializedName("ShowCurrentDateAsTime") + @Expose + private boolean showCurrentDateAsTime = false; + + @SerializedName("RequestLogon") + @Expose + private boolean requestLogon = false; + + @SerializedName("InfobaseDeniedFriendlyEditMode") + @Expose + private boolean infobaseDeniedFriendlyEditMode = true; + + @SerializedName("InfobaseDeniedMessagePattern") + @Expose + private String infobaseDeniedMessagePattern = ""; + @SerializedName("Servers") @Expose private Map servers = new HashMap<>(); + @SerializedName("IbasesPath") + @Expose + private String ibasesPath = ""; + @SerializedName("SessionColumnProperties") @Expose private ColumnProperties sessionColumnProperties = new ColumnProperties(0); @@ -146,9 +179,17 @@ public class Config { @Expose private ColumnProperties wsColumnProperties = new ColumnProperties(0); + @SerializedName("AssignmentRuleColumnProperties") + @Expose + private ColumnProperties asRuleColumnProperties = new ColumnProperties(0); + private static final Logger LOGGER = - LoggerFactory.getLogger("clusterAdminLibrary"); //$NON-NLS-1$ - private static final String DEFAULT_CONFIG_PATH = "config.json"; //$NON-NLS-1$ + (Logger) LoggerFactory.getLogger(Config.class.getSimpleName()); + + private static final Logger ROOT_LOGGER = + (Logger) LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); + + private static final String DEFAULT_CONFIG_PATH = "config.json"; // $NON-NLS-1$ private static final String TEMP_CONFIG_PATH = "config_temp.json"; //$NON-NLS-1$ public static Config currentConfig; @@ -195,8 +236,8 @@ public Config(String configPath) { // } // } - /** Init config. */ - public void init() { + /** Действия, которые нужно выполнить после чтения или создания конфига. */ + public void postInit() { runReadUpstreamVersion(); } @@ -206,8 +247,22 @@ public void migrateProps() { if (configVersion == null) { configVersion = "0.2.0"; servers.forEach((key, server) -> server.migrateProps(configVersion)); - configVersion = currentVersion.toString(); } + + if (!currentVersion.toString().equals(configVersion)) { + // делаем бекап конфига + String configCopy = configPath + "_bak"; + File configFile = new File(configPath); + if (configFile.exists()) { + try { + Files.copy(Path.of(configPath), Path.of(configCopy), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e) { + LOGGER.error("Config file backup error:", e); + } + } + } + + configVersion = currentVersion.toString(); } private OsType getOperatingSystemType() { @@ -249,7 +304,7 @@ private Version readCurrentVersion() { // return Version.parse(v); // } - return Version.parse("0.3.0"); + return Version.parse("0.4.0"); } private void runReadUpstreamVersion() { @@ -410,7 +465,6 @@ private void showDownloadedFile(String fname) { * @return новый сервер */ public Server createNewServer() { - Server newServer = null; if (isReadClipboard()) { Clipboard clipboard = new Clipboard(Display.getDefault()); @@ -420,16 +474,11 @@ public Server createNewServer() { if (clip != null && clip.startsWith("Srvr=")) { //$NON-NLS-1$ String[] srvrPart = clip.split(";"); //$NON-NLS-1$ String srvr = srvrPart[0].substring(6, srvrPart[0].length() - 1); - newServer = new Server(srvr); - } else { - newServer = new Server("Server:1541"); //$NON-NLS-1$ + return new Server(srvr); } - } else { - newServer = new Server("Server:1541"); //$NON-NLS-1$ } - // servers.put(newServer.getServerKey(), newServer); - // TODO по идее еще рано добавлять в список серверов эту заготовку - return newServer; + + return new Server(); } public void addNewServer(Server server) { @@ -458,29 +507,13 @@ public void close() { * Добавление новых серверов в конфиг. * * @param newServers - список новых серверов - * @return список серверов, которые были реально добавлены */ - public List addNewServers(List newServers) { - // Пакетное добавление серверов в список, предполагается для механизма импорта из списка - // информационных баз - - List addedServers = new ArrayList<>(); - - // Имя сервера, которое приходит сюда не равно Представлению сервера, выводимому в списке - // Имя сервера. оно же Key в map и json, строка вида Server:1541, с обязательным указанием порта - // менеджера, к которому подключаемся - // если порт менеджера не задан - ставим стандартный 1541 - // переделать - for (String serverName : newServers) { - if (!servers.containsKey(serverName)) { - Server serverConfig = new Server(serverName); - servers.put(serverName, serverConfig); - - addedServers.add(serverName); - } + public void addNewServers(List newServers) { + // Пакетное добавление серверов в список + for (Server server : newServers) { + servers.put(server.getServerKey(), server); } - - return addedServers; + saveConfig(); } /** Подключиться ко всем серверам в тихом режиме. */ @@ -511,6 +544,24 @@ public void setCheckingUpdate(boolean checkingUpdate) { this.checkingUpdate = checkingUpdate; } + /** + * Показывать только время в текущей дате. + * + * @return текущее значение + */ + public boolean showCurrentDateAsTime() { + return showCurrentDateAsTime; + } + + /** + * Установка отображения только времени в текущей дате. + * + * @param showCurrentDateAsTime - новое значение + */ + public void setShowCurrentDateAsTime(boolean showCurrentDateAsTime) { + this.showCurrentDateAsTime = showCurrentDateAsTime; + } + /** * Получает список зарегистрированных серверов. * @@ -844,13 +895,116 @@ public void setInfobasesSortDirection(InfobasesSortDirection sortDirection) { this.infobasesSortDirection = sortDirection; } + /** + * Получить установленный уровень логирования. + * + * @return уровень логирования + */ + public String getLoggerLevel() { + return loggerLevel; + } + + /** + * Установить уровень логирования. + * + * @param level - уровень логирования + */ + public void setLoggerLevel(String level) { + this.loggerLevel = level; + applyLoggerLevel(); + } + + /** Применить уровень логирования из конфига. */ + private void applyLoggerLevel() { + + ROOT_LOGGER.setLevel(Level.toLevel("info")); + ROOT_LOGGER.info("logger level switching to <{}>", loggerLevel); // $NON-NLS-1$ + ROOT_LOGGER.setLevel(Level.toLevel(loggerLevel)); + + ROOT_LOGGER.error("test logger level = error"); // $NON-NLS-1$ + ROOT_LOGGER.warn("test logger level = warn"); // $NON-NLS-1$ + ROOT_LOGGER.info("test logger level = info"); // $NON-NLS-1$ + ROOT_LOGGER.debug("test logger level = debug"); // $NON-NLS-1$ + } + + /** + * Получить частоту обновления списка. + * + * @return частота обновления списка (миллисекунд) + */ + public int getListRrefreshRate() { + return listRefreshRate; + } + + /** + * Установка частоты обновления списка. + * + * @param refreshRate - частота обновления списка (миллисекунд) + */ + public void setListRrefreshRate(int refreshRate) { + this.listRefreshRate = refreshRate; + } + + /** + * Запрашивать логин/пароль при действиях с базой. + * + * @return запрашивать или нет + */ + public boolean getRequestLogon() { + return requestLogon; + } + + /** + * Установка запроса логин/пароля при действиях с базой. + * + * @param requestLogon - запрашивать логин/пароль + */ + public void setRequestLogon(boolean requestLogon) { + this.requestLogon = requestLogon; + } + + /** + * Получить путь к файлу со списком информационных баз. + * + * @return Путь к списку информационных баз + */ + public Path getIbasesPath() { + if (ibasesPath.isBlank()) { + return Paths.get(System.getenv("APPDATA"), "1c\\1cestart\\ibases.v8i"); + } else { + return Paths.get(ibasesPath); + } + } + + /** + * Получить установленный пользователем путь к файлу со списком информационных баз. + * + * @return Путь к списку информационных баз в виде строки + */ + public String getIbasesStringPath() { + if (ibasesPath.isBlank()) { + return ""; + } else { + return ibasesPath; + } + } + + /** + * Установить путь к файлу со списком информационных баз. + * + * @param ibasesPath - путь к файлу со списком информационных баз + */ + public void setIbasesPath(String ibasesPath) { + this.ibasesPath = ibasesPath; + } + /** * Получение свойства колонок списков. * - * @param clazz - имя класса, идентифицирующее список-кладелец колонок + * @param clazz - имя класса, идентифицирующее список-владелец колонок * @return ColumnProperties - свойства колонок списка */ - public ColumnProperties getColumnsProperties(Class clazz) { + public ColumnProperties getColumnsProperties(Class clazz) { if (clazz == SessionInfoExtended.class) { return sessionColumnProperties; } else if (clazz == ConnectionInfoExtended.class) { @@ -861,6 +1015,8 @@ public ColumnProperties getColumnsProperties(Class c return wpColumnProperties; } else if (clazz == WorkingServerInfoExtended.class) { return wsColumnProperties; + } else if (clazz == IAssignmentRuleInfo.class) { + return asRuleColumnProperties; } else { return null; } @@ -872,7 +1028,7 @@ public ColumnProperties getColumnsProperties(Class c * @param clazz - имя класса, идентифицирующее список-кладелец колонок * @param columnOrder - новый порядок колонок */ - public void setColumnsOrder(Class clazz, int[] columnOrder) { + public void setColumnsOrder(Class clazz, int[] columnOrder) { getColumnsProperties(clazz).setOrder(columnOrder); } @@ -883,7 +1039,7 @@ public void setColumnsOrder(Class clazz, int[] colum * @param index - индекс колонки * @param width - ширина колонки */ - public void setColumnsWidth(Class clazz, int index, int width) { + public void setColumnsWidth(Class clazz, int index, int width) { getColumnsProperties(clazz).setWidth(index, width); } @@ -932,6 +1088,42 @@ public Version getLatestVersion() { return latestVersion; } + /** + * Установлен удобный вариант установки даты запрета входа в инфобазу. + * + * @return истина = удобный вариант установки даты + */ + public boolean getInfobaseDeniedFriendlyEditMode() { + return infobaseDeniedFriendlyEditMode; + } + + /** + * Устанавливает удобный вариант установки даты запрета входа в инфобазу. + * + * @param infobaseDeniedFriendlyEditMode - истина = удобный вариант установки даты + */ + public void setInfobaseDeniedFriendlyEditMode(boolean infobaseDeniedFriendlyEditMode) { + this.infobaseDeniedFriendlyEditMode = infobaseDeniedFriendlyEditMode; + } + + /** + * Возвращает шаблон текста запрета входа в инфобазу. + * + * @return Шаблон текста запрета входа + */ + public String getInfobaseDeniedMessagePattern() { + return infobaseDeniedMessagePattern; + } + + /** + * Устанавливает шаблон текста запрета входа в инфобазу. + * + * @param infobaseDeniedMessagePattern - Шаблон текста запрета входа + */ + public void setInfobaseDeniedMessagePattern(String infobaseDeniedMessagePattern) { + this.infobaseDeniedMessagePattern = infobaseDeniedMessagePattern; + } + /** * Возвращает путь к файлу конфига. * @@ -1012,14 +1204,18 @@ public static Config readConfig(String configPath) { config.setConfigPath(configPath); config.migrateProps(); - config.init(); + // config.init(); if (config.getLocale() != null) { LOGGER.debug("Set locale is <{}>", config.getLocale()); //$NON-NLS-1$ Locale locale = Locale.forLanguageTag(config.getLocale()); java.util.Locale.setDefault(locale); Messages.reloadBundle(locale); // TODO не совсем понятно как работает } + + config.applyLoggerLevel(); } + config.postInit(); + LOGGER.info("Config file read successfully"); //$NON-NLS-1$ return config; } diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Helper.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Helper.java index 50223a8..a003235 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Helper.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Helper.java @@ -1,10 +1,24 @@ package ru.yanygin.clusterAdminLibrary; +import java.io.BufferedReader; import java.io.File; +import java.io.FileReader; import java.io.FilenameFilter; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; @@ -19,10 +33,15 @@ public class Helper { private static final Logger LOGGER = LoggerFactory.getLogger("ClusterProvider"); //$NON-NLS-1$ + private static final DateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss"); + private static final DateFormat currentDayDateFormat = new SimpleDateFormat("HH:mm:ss"); + /** Пустой UUID. */ public static final UUID EMPTY_UUID = UUID.fromString("00000000-0000-0000-0000-000000000000"); //$NON-NLS-1$ + public static final String BOOSTY_LINK = "https://boosty.to/YanSergeyCoder"; + private Helper() {} /** @@ -43,7 +62,9 @@ public static Image getImage(String name) { * @param message - текст сообщения */ public static void showMessageBox(String message) { - MessageBox messageBox = new MessageBox(Display.getDefault().getActiveShell()); + MessageBox messageBox = + new MessageBox(Display.getDefault().getActiveShell()); // SWT.ICON_INFORMATION | SWT.OK + messageBox.setText("Information"); messageBox.setMessage(message); messageBox.open(); } @@ -65,10 +86,10 @@ public static int showQuestionBox(String question) { /** * Возвращает список установленных версий платформы V8. * - * @param config - конфиг программы + * @param bitness - разрядность платформы * @return список установленных версий платформы V8 */ - public static Map getInstalledV8Versions() { + public static Map getInstalledV8Versions(String bitness) { LOGGER.debug("Get installed v8 platform versions"); //$NON-NLS-1$ Map versions = new HashMap<>(); @@ -77,52 +98,116 @@ public static Map getInstalledV8Versions() { return versions; } - File v8x64CommonPath = new File("C:\\Program Files\\1cv8"); //$NON-NLS-1$ - File v8x86CommonPath = new File("C:\\Program Files (x86)\\1cv8"); //$NON-NLS-1$ + final String filterWindows = "8.3.\\d\\d.\\d{4}"; // $NON-NLS-1$ + final String filterLinux = "v8.3.\\d\\d.\\d{4}"; // $NON-NLS-1$ + String filterCurrentOs; + + Path v8runtimeDir; + // Path v8runtimeDirX64; + // Path v8runtimeDirX86; + + if (Config.currentConfig.isWindows()) { + filterCurrentOs = filterWindows; + // для 64-разрядной + // v8runtimeDirX64 = Paths.get(System.getenv("ProgramW6432"), "1cv8"); + // v8runtimeDirX86 = Paths.get(System.getenv("ProgramFiles(x86)"), "1cv8"); + // для 32-разрядной + // v8runtimeDirX86 = Paths.get(System.getenv("ProgramFiles"), "1cv8"); + + v8runtimeDir = + bitness.equals("x64") + ? Paths.get(System.getenv("ProgramW6432"), "1cv8") + : Paths.get(System.getenv("ProgramFiles(x86)"), "1cv8"); + + } else if (Config.currentConfig.isLinux()) { + // filterCurrentOs = filterLinux; + // v8runtimeDirX64 = Paths.get("/opt", "1C", "v8.3", "x86_64"); + // v8runtimeDirX86 = Paths.get("/opt", "1C", "v8.3", "i386"); + // v8runtimeDirX64 = Paths.get("/opt", "1cv8", "x86_64"); + // v8runtimeDirX86 = Paths.get("/opt", "1cv8", "i386"); + + // v8runtimeDir = Paths.get("/opt", "1C"); + return versions; + + } else if (Config.currentConfig.isMacOs()) { + // v8runtimeDir = Paths.get("/opt", "1cv8"); + return versions; + } else { + return versions; + } + LOGGER.debug("Current v8 runtime directory <{}>", v8runtimeDir); // $NON-NLS-1$ + + // File v8x64CommonPath = new File("C:\\Program Files\\1cv8"); // $NON-NLS-1$ + // File v8x86CommonPath = new File("C:\\Program Files (x86)\\1cv8"); // $NON-NLS-1$ - FilenameFilter filter = + FilenameFilter filterVersion = new FilenameFilter() { @Override public boolean accept(File f, String name) { - return name.matches("8.3.\\d\\d.\\d{4}"); //$NON-NLS-1$ + return Paths.get(f.getAbsolutePath(), name).toFile().isDirectory() + && name.matches(filterCurrentOs); } }; - try { - if (v8x64CommonPath.exists()) { - File[] v8x64dirs = v8x64CommonPath.listFiles(filter); - for (File dir : v8x64dirs) { - if (dir.isDirectory()) { - File ras = new File(dir.getAbsolutePath().concat("\\bin\\ras.exe")); //$NON-NLS-1$ - if (ras.exists() && ras.isFile()) { - versions.put(dir.getName().concat(" (x86_64)"), ras.getAbsolutePath()); //$NON-NLS-1$ - } + FilenameFilter filterBitnessLinux = + new FilenameFilter() { + @Override + public boolean accept(File f, String name) { + String bitnessPart = bitness.equals("x64") ? "x86_64" : "i386"; + return Paths.get(f.getAbsolutePath(), name).toFile().isDirectory() + && Paths.get(f.getAbsolutePath(), name, bitnessPart).toFile().exists(); } - } - } - } catch (Exception excp) { - LOGGER.error("Error read dir <{}>", v8x64CommonPath.getAbsolutePath(), excp); //$NON-NLS-1$ - } + }; try { - if (v8x86CommonPath.exists()) { - File[] v8x86dirs = v8x86CommonPath.listFiles(filter); - for (File dir : v8x86dirs) { - if (dir.isDirectory()) { - File ras = new File(dir.getAbsolutePath().concat("\\bin\\ras.exe")); //$NON-NLS-1$ - if (ras.exists() && ras.isFile()) { - versions.put(dir.getName(), ras.getAbsolutePath()); //$NON-NLS-1$ - } + if (v8runtimeDir.toFile().exists()) { + File[] versionDirs = v8runtimeDir.toFile().listFiles(filterVersion); + for (File dir : versionDirs) { + LOGGER.debug("Version dir <{}>", dir); // $NON-NLS-1$ + + if (Config.currentConfig.isWindows()) { + versions.put(dir.getName(), dir.getAbsolutePath()); + } else if (dir.list(filterBitnessLinux).length > 0) { + versions.put(dir.getName(), dir.getAbsolutePath()); } } } } catch (Exception excp) { - LOGGER.error("Error read dir <{}>", v8x64CommonPath.getAbsolutePath(), excp); //$NON-NLS-1$ + LOGGER.error( + "Error read dir <{}>", v8runtimeDir.toFile().getAbsolutePath(), excp); // $NON-NLS-1$ } return versions; } + /** + * Возвращает путь к исполняемому файлу RAS. + * + * @param version - версия платформы + * @param bitness - разрядность версии + * @return путь к исполняемому файлу RAS + */ + public static String pathToRas(String version, String bitness) { + + String pathToVersion = getInstalledV8Versions(bitness).get(version); + String osPart; + + if (pathToVersion == null) { + // указанная версия не обнаружена среди установленных + return null; + } + + if (Config.currentConfig.isWindows()) { + osPart = "bin"; + } else if (Config.currentConfig.isLinux()) { + osPart = bitness.equals("x64") ? "x86_64" : "i386"; + } else { + return null; + } + + return Paths.get(pathToVersion, osPart, "ras").toFile().getAbsolutePath(); + } + /** * Получает белый цвет. * @@ -203,4 +288,106 @@ public static Color getOrangeColor() { public static Color getTurquoiseColor() { return new Color(0, 128, 128); } + + /** + * Преобразует дату к строке. + * + * @param date - Дата + * @return Дата строкой + */ + public static String dateToString(Date date) { + Date emptyDate = new Date(0); + if (date == null || date.equals(emptyDate)) { + return ""; + } + Calendar startCurrentDay = new GregorianCalendar(); + startCurrentDay.set(Calendar.HOUR_OF_DAY, 0); + startCurrentDay.set(Calendar.MINUTE, 0); + startCurrentDay.set(Calendar.SECOND, 0); + + if (Config.currentConfig.showCurrentDateAsTime() && date.after(startCurrentDay.getTime())) { + return currentDayDateFormat.format(date); + } else { + return simpleDateFormat.format(date); + } + } + + + /** Ищет новые сервера в файле списка инфобаз v8i. */ + public static List findNewServers() { + List foundServersKey = new ArrayList<>(); + List foundServers = new ArrayList<>(); + Map currentServers = Config.currentConfig.getServers(); + + // Читаем файл со списком инфобаз стартера + Path ibasesPath = Config.currentConfig.getIbasesPath(); + String ibasesText = readTextFile(ibasesPath); + + if (!ibasesText.isBlank()) { + + Pattern p = Pattern.compile("Srvr=\"(.*?)\";Ref"); + Matcher m = p.matcher(ibasesText); + while (m.find()) { + String serverAddress = m.group(1).toLowerCase(); + + String[] adr = serverAddress.split(":"); // $NON-NLS-1$ + String agentHost = adr[0]; + int agentPort = (adr.length == 1) ? 1540 : Integer.valueOf(adr[1]) - 1; + + Server server = new Server(agentHost, agentPort); + String serverKey = server.getServerKey(); + + if (!foundServersKey.contains(serverKey) && currentServers.get(serverKey) == null) { + foundServersKey.add(serverKey); + foundServers.add(server); + } + } + } + + // читаем файл со списком серверов зарегистрированных в штатной консоли + Path srvPath = Paths.get(System.getenv("LOCALAPPDATA"), "1c\\1cv8\\appsrvrs.lst"); + String srvText = readTextFile(srvPath); + + if (!srvText.isBlank()) { + Pattern p = Pattern.compile("\\{\"tcp\",(.*,.*?),.*\\}"); + Matcher m = p.matcher(srvText); + while (m.find()) { + String serverAddress = m.group(1).toLowerCase(); + + String[] adr = serverAddress.split(","); // $NON-NLS-1$ + String agentHost = adr[0].replace("\"", ""); + int agentPort = Integer.parseInt(adr[1]); + + Server server = new Server(agentHost, agentPort); + String serverKey = server.getServerKey(); + + if (!foundServersKey.contains(serverKey) && currentServers.get(serverKey) == null) { + foundServersKey.add(serverKey); + foundServers.add(server); + } + } + } + + return foundServers; + } + + private static String readTextFile(Path textFile) { + if (textFile.toFile().exists()) { + try (BufferedReader br = new BufferedReader(new FileReader(textFile.toFile()))) { + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + while (line != null) { + sb.append(line); + sb.append(System.lineSeparator()); + line = br.readLine(); + } + return sb.toString(); + } catch (IOException excp) { + LOGGER.error("Error: ", excp); // $NON-NLS-1$ + return ""; + } + } + + return ""; + } } diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Server.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Server.java index 160c948..12b3dc9 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Server.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/Server.java @@ -30,6 +30,7 @@ import com._1c.v8.ibis.admin.client.IAgentAdminConnectorFactory; import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; +import java.lang.Runtime.Version; import java.text.Collator; import java.util.ArrayList; import java.util.Collections; @@ -40,7 +41,9 @@ import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.TreeItem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.yanygin.clusterAdminLibraryUI.AuthenticateDialog; @@ -55,19 +58,19 @@ public class Server implements Comparable { @SerializedName("AgentHost") @Expose - private String agentHost = ""; //$NON-NLS-1$ + private String agentHost = "Server1c"; //$NON-NLS-1$ @SerializedName("AgentPort") @Expose - private int agentPort = 0; + private int agentPort = 1540; @SerializedName("RasHost") @Expose - private String rasHost = ""; //$NON-NLS-1$ + private String rasHost = "Server1c"; //$NON-NLS-1$ @SerializedName("RasPort") @Expose - private int rasPort = 0; + private int rasPort = 1545; @SerializedName("UseLocalRas") @Expose @@ -77,9 +80,9 @@ public class Server implements Comparable { @Expose private int localRasPort = 0; - @SerializedName("LocalRasV8version") + @SerializedName("V8Version") @Expose - private String localRasV8version = ""; //$NON-NLS-1$ + private String v8version = ""; //$NON-NLS-1$ @SerializedName("Autoconnect") @Expose @@ -87,7 +90,7 @@ public class Server implements Comparable { @Deprecated(since = "0.3.0", forRemoval = true) @SerializedName("SaveCredentials") - @Expose(serialize = false, deserialize = true) // TODO верно ли написал + @Expose(serialize = false, deserialize = true) private boolean saveCredentials = false; @SerializedName("SaveCredentialsVariant") @@ -96,12 +99,12 @@ public class Server implements Comparable { @Deprecated(since = "0.3.0", forRemoval = true) @SerializedName("AgentUser") - @Expose(serialize = false, deserialize = true) // TODO верно ли написал + @Expose(serialize = false, deserialize = true) private String agentUserName = ""; //$NON-NLS-1$ @Deprecated(since = "0.3.0", forRemoval = true) @SerializedName("AgentPassword") - @Expose(serialize = false, deserialize = true) // TODO верно ли написал + @Expose(serialize = false, deserialize = true) private String agentPassword = ""; //$NON-NLS-1$ @SerializedName("AgentCredential") @@ -110,7 +113,7 @@ public class Server implements Comparable { @Deprecated(since = "0.3.0", forRemoval = true) @SerializedName("ClustersCredentials") - @Expose(serialize = false, deserialize = true) // TODO верно ли написал + @Expose(serialize = false, deserialize = true) private Map clustersCredentialsOld = new HashMap<>(); @SerializedName("ClustersCredentialsV3") @@ -125,11 +128,13 @@ public class Server implements Comparable { @Expose private List favoriteInfobases = new ArrayList<>(); - + private ServerState serverState = ServerState.DISCONNECT; private boolean available; private Process localRasProcess; - private String connectionError = ""; //$NON-NLS-1$; - // private String agentVersion = ""; //$NON-NLS-1$ + private String connectionError = ""; //$NON-NLS-1$ + boolean silentConnectionMode = false; + + @Deprecated private String agentVersion = Messages.getString("Server.NotConnect"); //$NON-NLS-1$ private IAgentAdminConnector agentConnector; @@ -149,6 +154,18 @@ public class Server implements Comparable { private static final String TREE_TITLE_PATTERN = "%s (%s)"; //$NON-NLS-1$ + private static Image defaultIcon = Helper.getImage("server_default_24.png"); // $NON-NLS-1$ + private static Image connectedIcon = Helper.getImage("server_connected_24.png"); // $NON-NLS-1$ + private static Image connectingIcon = Helper.getImage("server_connecting_24.png"); // $NON-NLS-1$ + private static Image connectErrorIcon = Helper.getImage("server_connectError_24.png"); // $NON-NLS-1$ + + private enum ServerState { + DISCONNECT, + CONNECTED, + CONNECTING, + CONNECT_ERROR + } + public enum SaveCredentialsVariant { DISABLE, NAME, @@ -322,39 +339,39 @@ public void setLocalRasPort(int localRasPort) { } /** - * Получение версии v8 локального RAS. + * Получение версии платформы v8 1C-сервера. * - * @return версия v8 локального RAS + * @return версия платформы v8 1C-сервера */ - public String getLocalRasV8version() { - return localRasV8version; + public String getV8Version() { + return this.v8version; } /** - * Установка версии v8 локального RAS. + * Установка версии платформы v8 1C-сервера. * - * @param localRasV8version - версия v8 локального RAS + * @param v8version - версия платформы v8 1C-сервера */ - public void setLocalRasV8version(String localRasV8version) { - this.localRasV8version = localRasV8version; + public void setV8Version(String v8version) { + this.v8version = v8version; } /** - * Получение версии агента сервера. + * Получение строки с ошибкой подключения к серверу. * - * @return версия агента сервера + * @return ошибка подключения */ - public String getAgentVersion() { - return agentVersion; + public String getConnectionError() { + return connectionError; } /** - * Получение строки с ошибкой подключения к серверу. + * Показывает, нужно ли выводить ошибку подключения. * - * @return ошибка подключения + * @return выводить ошибку подключения */ - public String getConnectionError() { - return connectionError; + public boolean needShowConnectionError() { + return !connectionError.isBlank() && !silentConnectionMode; } /** @@ -363,7 +380,7 @@ public String getConnectionError() { * @return ключ сервера */ public String getServerKey() { - return agentHost.concat(":").concat(Integer.toString(agentPort)); //$NON-NLS-1$ + return agentHost.toLowerCase().concat(":").concat(Integer.toString(agentPort)); // $NON-NLS-1$ } /** @@ -381,7 +398,7 @@ public String getTreeTitle() { : ""; //$NON-NLS-1$ var serverVersionPatternPart = commonConfig.isShowServerVersion() - ? String.format(" (%s)", agentVersion) //$NON-NLS-1$ + ? String.format(" (%s)", v8version) //$NON-NLS-1$ : ""; //$NON-NLS-1$ var serverDescriptionPatternPart = commonConfig.isShowServerDescription() && !description.isBlank() @@ -596,8 +613,12 @@ public Server() { * @param serverName - имя сервера в виде "Server" или с указанием порта менеджера "Server:2541". */ public Server(String serverName) { + serverName = serverName.strip(); + if (serverName.isBlank()) { + return; + } - computeServerParams(serverName); + computeHostAndPort(serverName); // this.useLocalRas = false; // this.localRasPort = 0; @@ -610,6 +631,20 @@ public Server(String serverName) { // init(); } + /** + * Создание нового экземпляра. + * + * @param serverHost - имя хоста сервера в виде "Server" (без номера порта) + * @param agentPort - порт агента сервера (1540, 2540 и т.п.) + */ + public Server(String serverHost, int agentPort) { + + this.agentHost = serverHost; + this.rasHost = serverHost; + this.agentPort = agentPort; + this.rasPort = agentPort + 5; + } + /** Initializes some server parameters. */ // public void init() { // @@ -681,19 +716,57 @@ public int compareTo(Server o) { return collator.compare(secondString, firstString); } - private void readAgentVersion() { + private void refreshAgentVersion() { if (!isConnected()) { return; } - + + String newAgentVersionString = ""; try { - agentVersion = agentConnection.getAgentVersion(); - LOGGER.debug( - "Agent version of server <{}> is <{}>", this.getServerKey(), agentVersion); //$NON-NLS-1$ + newAgentVersionString = agentConnection.getAgentVersion(); } catch (Exception e) { - agentVersion = Messages.getString("Server.UnknownAgentVersion"); //$NON-NLS-1$ - LOGGER.error("Unknown agent version of server <{}>", this.getServerKey()); //$NON-NLS-1$ + // для платформы 8.3.10 и ниже agentConnection.getAgentVersion() бросает AgentAdminException + this.v8version = Messages.getString("Server.UnknownAgentVersion"); // $NON-NLS-1$ + LOGGER.error("Unknown agent version of server <{}>", this.getServerKey()); // $NON-NLS-1$ + return; + } + + if (this.v8version.isEmpty()) { + this.v8version = newAgentVersionString; + LOGGER.debug( + "Set Server <{}> version is <{}>", this.getServerKey(), this.v8version); //$NON-NLS-1$ + return; + } + + // agentVersion = agentConnection.getAgentVersion() = [8, 3, 18, 1483] + // agentVersion.feature() = 8 + // agentVersion.interim() = 3 + // agentVersion.update() = 18 + // agentVersion.patch() = 1483 + // для платформы 8.3.15 и ниже agentVersion.patch() = 0 всегда + + Version newAgentVersion = Version.parse(newAgentVersionString); + Version savedV8version = Version.parse(this.v8version); + + boolean v8versionIsActual; + + if (newAgentVersion.version().size() == 3) { + v8versionIsActual = + savedV8version.feature() == newAgentVersion.feature() + && savedV8version.interim() == newAgentVersion.interim() + && savedV8version.update() == newAgentVersion.update(); + + } else { + v8versionIsActual = savedV8version.equals(newAgentVersion); + } + + if (!v8versionIsActual) { + this.v8version = newAgentVersionString; + LOGGER.debug( + "Refresh Server <{}> version is <{}>", //$NON-NLS-1$ + this.getServerKey(), + this.v8version); } } @@ -715,7 +788,7 @@ private String getLocalisedMessage(Throwable excp) { * @return {@code true} если v8 версия 8.3.15 или выше */ public boolean isFifteenOrMoreAgentVersion() { - return agentVersion.compareTo("8.3.15") >= 0; //$NON-NLS-1$ + return v8version.compareTo("8.3.15") >= 0; //$NON-NLS-1$ } /** @@ -724,21 +797,16 @@ public boolean isFifteenOrMoreAgentVersion() { * @param serverAddress - Имя сервера из списка баз. Может содержать номер порта менеджера * кластера (Если не указан, то по-умолчанию 1541). Примеры: Server1c, Server1c:2541 */ - private void computeServerParams(String serverAddress) { - - String host; - int newAgentPort; - int newRasPort; + private void computeHostAndPort(String serverAddress) { - serverAddress = serverAddress.strip(); - if (serverAddress.isBlank()) { - serverAddress = "localhost"; //$NON-NLS-1$ - } + String[] adr = serverAddress.split(":"); // $NON-NLS-1$ - String[] adr = serverAddress.split(":"); //$NON-NLS-1$ - host = adr[0]; + final String host = adr[0]; + final int newAgentPort; + final int newRasPort; if (adr.length == 1) { + // адрес не содержит двоеточие и номер порта, значит используется порт по-умолчанию 1541 newAgentPort = 1540; newRasPort = 1545; } else { @@ -752,7 +820,7 @@ private void computeServerParams(String serverAddress) { this.agentPort = newAgentPort; this.rasPort = newRasPort; - LOGGER.info("Compute params for Server <{}> ", this.getServerKey()); //$NON-NLS-1$ + LOGGER.info("Compute host and port for Server <{}> ", this.getServerKey()); //$NON-NLS-1$ } /** @@ -763,7 +831,10 @@ private void computeServerParams(String serverAddress) { public boolean isConnected() { boolean isConnected = (agentConnection != null); - if (!isConnected) { + if (isConnected) { + serverState = ServerState.CONNECTED; + } else if (serverState != ServerState.CONNECTING) { + serverState = ServerState.DISCONNECT; LOGGER.info( "The connection a server <{}> is not established", //$NON-NLS-1$ this.getServerKey()); @@ -786,22 +857,39 @@ public boolean connectToServer(boolean disconnectAfter, boolean silentMode) { return true; } + available = false; + connectionError = ""; + serverState = ServerState.CONNECTING; + silentConnectionMode = silentMode; + + // все вызовы здесь проверить на Helper.showMessageBox + // этого тут быть не должно, потому что выполняется в отдельном потоке + if (!checkAndRunLocalRas()) { + serverState = ServerState.DISCONNECT; return false; } String currentRasHost = useLocalRas ? "localhost" : this.rasHost; //$NON-NLS-1$ int currentRasPort = useLocalRas ? localRasPort : this.rasPort; - + // try { + // Thread.sleep(5000); + // } catch (InterruptedException e) { // TODO Искусственная задержка подключения + // e.printStackTrace(); + // } try { - connectToAgent(currentRasHost, currentRasPort, 20); + connectToAgent(currentRasHost, currentRasPort, 120); + serverState = ServerState.CONNECTED; if (disconnectAfter) { disconnectFromAgent(); + serverState = ServerState.DISCONNECT; } } catch (Exception excp) { available = false; + serverState = ServerState.CONNECT_ERROR; + disconnectLocalRas(); connectionError = @@ -810,9 +898,9 @@ public boolean connectToServer(boolean disconnectAfter, boolean silentMode) { this.getServerKey(), getLocalisedMessage(excp)); LOGGER.error(connectionError); - if (!silentMode) { - Helper.showMessageBox(connectionError); - } + // if (!silentMode) { + // Helper.showMessageBox(connectionError); + // } return false; } return true; @@ -834,28 +922,34 @@ private boolean checkAndRunLocalRas() { return true; } - if (localRasV8version.isBlank() || localRasPort == 0) { - var message = + if (v8version.isBlank() || localRasPort == 0) { + connectionError = String.format( - Messages.getString("Server.LocalRasParamsIsEmpty"), //$NON-NLS-1$ + Messages.getString("Server.LocalRasParamsIsEmpty"), // $NON-NLS-1$ this.getServerKey()); - LOGGER.error(message); - Helper.showMessageBox(message); + LOGGER.error(connectionError); + return false; + } + Version savedV8version = Version.parse(v8version); + if (savedV8version.version().size() == 3) { + connectionError = + String.format( + Messages.getString("Server.LocalRasParamsIsInvalid"), // $NON-NLS-1$ + v8version); + LOGGER.error(connectionError); return false; } ///////////////////////////// пока только Windows var processBuilder = new ProcessBuilder(); var processOutput = ""; //$NON-NLS-1$ - var localRasPath = Helper.getInstalledV8Versions().get(localRasV8version); + var localRasPath = Helper.pathToRas(v8version, "x64"); if (localRasPath == null) { - var message = + connectionError = String.format( - Messages.getString("Server.LocalRasNotFound"), this.getServerKey()); //$NON-NLS-1$ - LOGGER.error(message); - Helper.showMessageBox(message); - + Messages.getString("Server.LocalRasNotFound"), this.getServerKey()); // $NON-NLS-1$ + LOGGER.error(connectionError); return false; } @@ -881,8 +975,7 @@ private boolean checkAndRunLocalRas() { } catch (Exception excp) { LOGGER.error("Error launch local RAS for server <{}>", this.getServerKey()); //$NON-NLS-1$ LOGGER.error("Error: <{}>", processOutput, excp); //$NON-NLS-1$ - Helper.showMessageBox(excp.getLocalizedMessage()); - + connectionError = excp.getLocalizedMessage(); return false; } @@ -909,8 +1002,6 @@ private boolean checkAndRunLocalRas() { connectionError = String.format("Local RAS <%s> is shutdown", this.getServerKey()); //$NON-NLS-1$ LOGGER.error(connectionError); - Helper.showMessageBox(connectionError); - return false; } } @@ -922,7 +1013,7 @@ private boolean checkAndRunLocalRas() { * @param clusterId - ID кластера * @return boolean истекла/не истекла */ - private boolean checkAutenticateAgent() { + public boolean checkAutenticateAgent() { var needAuthenticate = false; try { @@ -938,8 +1029,8 @@ private boolean checkAutenticateAgent() { String[] rightStrings = { // TODO проверить английские варианты "Недостаточно прав пользователя на управление центральным сервером", "Администратор центрального сервера не аутентифицирован", - "The user's rights to manage the central server are insufficient", - "The administrator of the central server is not authenticated" + "The user's rights to manage the central server are insufficient", // не проверено + "Main server administrator is not authenticated" }; for (String rightString : rightStrings) { if (excp.getLocalizedMessage().contains(rightString)) { @@ -970,6 +1061,7 @@ private void connectToAgent(String address, int port, long timeout) { "The connection to server <{}> is already established", //$NON-NLS-1$ this.getServerKey()); available = true; + connectionError = ""; // $NON-NLS-1$ return; } @@ -985,7 +1077,7 @@ private void connectToAgent(String address, int port, long timeout) { available = true; connectionError = ""; //$NON-NLS-1$ - readAgentVersion(); + refreshAgentVersion(); LOGGER.debug("Server <{}> is connected now", this.getServerKey()); //$NON-NLS-1$ } @@ -1015,14 +1107,16 @@ public void disconnectFromAgent() { } finally { agentConnection = null; agentConnector = null; + serverState = ServerState.DISCONNECT; } } private void disconnectLocalRas() { - if (useLocalRas && localRasProcess.isAlive()) { + if (localRasProcess != null && localRasProcess.isAlive()) { Stream ch = localRasProcess.children(); ch.forEach(ProcessHandle::destroy); localRasProcess.destroy(); + localRasProcess = null; LOGGER.info( "Local RAS of Server <{}> is shutdown now", //$NON-NLS-1$ this.getServerKey()); @@ -1098,8 +1192,8 @@ private boolean checkAutenticateCluster(UUID clusterId) { String[] rightStrings = { // TODO проверить английские варианты "Недостаточно прав пользователя на управление кластером", "Администратор кластера не аутентифицирован", - "Insufficient user rights to manage the cluster", - "The cluster administrator is not authenticated" + "Insufficient user rights to manage cluster", + "The cluster administrator is not authenticated" // не проверено }; for (String rightString : rightStrings) { if (excp.getLocalizedMessage().toLowerCase().contains(rightString.toLowerCase())) { @@ -1377,6 +1471,16 @@ public IClusterInfo getClusterInfo(UUID clusterId) { return clusterInfo; } + /** + * Получение порта менеджера кластера. + * + * @param clusterId - ID кластера + * @return String - порт менеджера кластера + */ + public String getClusterMainPort(UUID clusterId) { + IClusterInfo clusterInfo = getClusterInfo(clusterId); + return clusterInfo == null ? "0" : String.valueOf(clusterInfo.getMainPort()); + } /** * Gets the list of cluster manager descriptions. * @@ -1547,16 +1651,71 @@ public boolean unregCluster(UUID clusterId) { * @param clusterId - ID кластера * @return список администраторов кластера */ - private List getClusterAdmins(UUID clusterId) { + public List getClusterAdmins(UUID clusterId) { LOGGER.debug( - "Gets the list of cluster administrators in the cluster <{}>", //$NON-NLS-1$ + "Getting a list of cluster administrators <{}>", //$NON-NLS-1$ clusterId); + if (!isConnected()) { + LOGGER.debug( + "The connection a cluster <{}> is not established", //$NON-NLS-1$ + clusterId); return new ArrayList<>(); } - // TODO - return null; + if (!checkAutenticateCluster(clusterId)) { + return new ArrayList<>(); + } + + List clusterAdmins; + try { + clusterAdmins = agentConnection.getClusterAdmins(clusterId); + } catch (Exception excp) { + LOGGER.error( + "Error getting the list of cluster administrators", //$NON-NLS-1$ + excp); + return new ArrayList<>(); + } + + return clusterAdmins; + } + + /** + * Регистрация нового или изменение существующего администратора кластера. + * + *

Требует аутентификации в кластере + * + * @param clusterId - ID кластера + * @param info - информация о администраторе + * @return {@code true} в случае успешной регистрации + */ + public boolean regClusterAdmin(UUID clusterId, IRegUserInfo info) { + LOGGER.debug( + "Administrator registration on the cluster <{}>", //$NON-NLS-1$ + clusterId); + + if (!isConnected()) { + LOGGER.debug( + "The connection a cluster <{}> is not established", //$NON-NLS-1$ + clusterId); + return false; + } + + if (!checkAutenticateCluster(clusterId)) { + return false; + } + + try { + agentConnection.regClusterAdmin(clusterId, info); + } catch (Exception excp) { + LOGGER.error( + "Error registering the administrator of the cluster", //$NON-NLS-1$ + excp); + Helper.showMessageBox(excp.getLocalizedMessage()); + return false; + } + + return true; } /** @@ -1565,18 +1724,142 @@ private List getClusterAdmins(UUID clusterId) { *

Требует аутентификации в кластере * * @param clusterId - ID кластера - * @param name - имя администратора + * @param username - имя администратора */ - private void unregClusterAdmin(UUID clusterId, String name) { + public boolean unregClusterAdmin(UUID clusterId, String username) { LOGGER.debug( - "Deletes a cluster administrator in the cluster <{}>", //$NON-NLS-1$ + "Deletes the cluster administrator in the cluster <{}>", //$NON-NLS-1$ clusterId); if (!isConnected()) { - return; + LOGGER.debug( + "The connection a cluster <{}> is not established", //$NON-NLS-1$ + clusterId); + return false; } - // TODO - return; + if (!checkAutenticateCluster(clusterId)) { + return false; + } + + try { + agentConnection.unregClusterAdmin(clusterId, username); + } catch (Exception excp) { + LOGGER.error( + "Error unregistration cluster administrator", //$NON-NLS-1$ + excp); + Helper.showMessageBox(excp.getLocalizedMessage()); + return false; + } + + return true; + } + + /** + * Получение списка администраторов центрального сервера. + * + *

Требует аутентификации на центральном сервере + * + * @return список администраторов кластера + */ + public List getAgentAdmins() { + LOGGER.debug( + "Getting the list of administrators on the main server <{}>", //$NON-NLS-1$ + getServerKey()); + + if (!isConnected()) { + LOGGER.debug( + "The connection a server <{}> is not established", //$NON-NLS-1$ + getServerKey()); + return new ArrayList<>(); + } + + if (!checkAutenticateAgent()) { + return new ArrayList<>(); + } + + List clusterAdmins; + try { + clusterAdmins = agentConnection.getAgentAdmins(); + } catch (Exception excp) { + LOGGER.error( + "Error getting the list of administrators of the main server", //$NON-NLS-1$ + excp); + return new ArrayList<>(); + } + + return clusterAdmins; + } + + /** + * Регистрация нового или изменение существующего администратора центрального сервера. + * + *

Требует аутентификации на центральном сервере + * + * @param info - информация о администраторе + * @return {@code true} в случае успешной регистрации + */ + public boolean regAgentAdmin(IRegUserInfo info) { + LOGGER.debug( + "Administrator registration on the main server <{}>", //$NON-NLS-1$ + getServerKey()); + + if (!isConnected()) { + LOGGER.debug( + "The connection a server <{}> is not established", //$NON-NLS-1$ + getServerKey()); + return false; + } + + if (!checkAutenticateAgent()) { + return false; + } + + try { + agentConnection.regAgentAdmin(info); + } catch (Exception excp) { + LOGGER.error( + "Error registering the administrator of the main server", //$NON-NLS-1$ + excp); + Helper.showMessageBox(excp.getLocalizedMessage()); + return false; + } + + return true; + } + + /** + * Удаление администратора центрального сервера. + * + *

Требует аутентификации на центральном сервере + * + * @param username - имя администратора + */ + public boolean unregAgentAdmin(String username) { + LOGGER.debug( + "Deleting an administrator on the main server <{}>", //$NON-NLS-1$ + getServerKey()); + if (!isConnected()) { + LOGGER.debug( + "The connection a server <{}> is not established", //$NON-NLS-1$ + getServerKey()); + return false; + } + + if (!checkAutenticateAgent()) { + return false; + } + + try { + agentConnection.unregAgentAdmin(username); + } catch (Exception excp) { + LOGGER.error( + "Error unregistration of the main server administrator", //$NON-NLS-1$ + excp); + Helper.showMessageBox(excp.getLocalizedMessage()); + return false; + } + + return true; } /** @@ -3108,77 +3391,206 @@ public List getClusterServices(UUID clusterId) { } /** - * Applies assignment rules. + * Получает список описаний ТНФ рабочего сервера. * *

Требует аутентификации в кластере * * @param clusterId - ID кластера - * @param full - assigment rule application mode: 0 - partial 1 - full + * @param serverId - ID рабочего сервера + * @return список ТНФ */ - public void applyAssignmentRules(UUID clusterId, int full) { - // TODO - agentConnection.applyAssignmentRules(clusterId, full); + public List getAssignmentRules(UUID clusterId, UUID serverId) { + LOGGER.debug( + "Getting a list of descriptions of assignment rules, cluster <{}>, ws <{}>", //$NON-NLS-1$ + clusterId, + serverId); + + if (!isConnected()) { + return new ArrayList<>(); + } + if (!checkAutenticateCluster(clusterId)) { + return new ArrayList<>(); + } + + List assignmentRules; + try { + assignmentRules = agentConnection.getAssignmentRules(clusterId, serverId); + } catch (Exception excp) { + LOGGER.error( + "Error in getting a list of descriptions of assignment rules", excp); // $NON-NLS-1$ + return new ArrayList<>(); + } + + assignmentRules.forEach( + rule -> + LOGGER.debug( + "\tRule: ObjectType=<{}>, RuleId=<{}>", //$NON-NLS-1$ + rule.getObjectType(), + rule.getAssignmentRuleId())); + + LOGGER.debug("Getting the list of assignment rule descriptions was successful"); // $NON-NLS-1$ + return assignmentRules; } /** - * Gets the list of descriptions of working server assignment rules. + * Получает описание правила ТНФ. * *

Требует аутентификации в кластере * * @param clusterId - ID кластера - * @param serverId - server ID - * @return infobase full infobase description + * @param serverId - ID рабочего сервера + * @param ruleId - ID правила ТНФ + * @return описание правила ТНФ */ - public List getAssignmentRules(UUID clusterId, UUID serverId) { - // TODO - return agentConnection.getAssignmentRules(clusterId, serverId); + public IAssignmentRuleInfo getAssignmentRuleInfo(UUID clusterId, UUID serverId, UUID ruleId) { + LOGGER.debug( + "Getting a description of the assignment rule, cluster <{}>, ws <{}>, rule <{}>", //$NON-NLS-1$ + clusterId, + serverId, + ruleId); + + if (!isConnected()) { + return null; + } + if (!checkAutenticateCluster(clusterId)) { + return null; + } + + IAssignmentRuleInfo assignmentRule; + try { + assignmentRule = agentConnection.getAssignmentRuleInfo(clusterId, serverId, ruleId); + } catch (Exception excp) { + LOGGER.error( + "Error in getting a list of descriptions of assignment rules", excp); // $NON-NLS-1$ + return null; + } + + LOGGER.debug( + "\tAssignment rule: ObjectType=<{}>", //$NON-NLS-1$ + assignmentRule.getObjectType()); + + LOGGER.debug("Getting the list of assignment rule descriptions was successful"); // $NON-NLS-1$ + return assignmentRule; } /** - * Creates an assignment rule, changes an existing one, or moves an existing rule to a new - * position. + * Создает правило ТНФ, изменяет существующее или переносит существующее правило в новую позицию. * *

Требует аутентификации в кластере * * @param clusterId - ID кластера - * @param serverId - server ID - * @param info - assignment rule description - * @param position - position in the rule list (starts from 0) - * @return ID of the created rule, or null if an existing assignment rule was changed + * @param serverId - ID рабочего сервера + * @param info - правило ТНФ + * @param position - позиция в списке правил (начинается с 0) + * @return ID созданного правила или null, если существующее правило было изменено */ - public UUID regAssignmentRule( + public boolean regAssignmentRule( UUID clusterId, UUID serverId, IAssignmentRuleInfo info, int position) { + + LOGGER.debug( + "Registration assignment rule <{}>", //$NON-NLS-1$ + info.getObjectType()); + + if (!isConnected()) { + return false; + } + if (!checkAutenticateCluster(clusterId)) { + return false; + } + + UUID newRuleId; + try { + newRuleId = agentConnection.regAssignmentRule(clusterId, serverId, info, position); + } catch (Exception excp) { + LOGGER.error( + "Error registraion assignment rule", //$NON-NLS-1$ + excp); + return false; + } + + if (newRuleId.equals(Helper.EMPTY_UUID)) { + LOGGER.debug( + "Registration new assignment rule <{}> succesful", //$NON-NLS-1$ + newRuleId); + } else { + LOGGER.debug( + "Registration changes a assignment rule <{}> was succesful", //$NON-NLS-1$ + info.getAssignmentRuleId()); + } + // TODO - return agentConnection.regAssignmentRule(clusterId, serverId, info, position); + return true; } /** - * Deletes an assignment rule from the list of working server rules. + * Удаляет правило ТНФ из списка правил рабочего сервера. * *

Требует аутентификации в кластере * * @param clusterId - ID кластера - * @param serverId - working server ID - * @param ruleId - assignment rule ID + * @param serverId - ID рабочего сервера + * @param ruleId - ID правила ТНФ */ - public void unregAssignmentRule(UUID clusterId, UUID serverId, UUID ruleId) { - // TODO - agentConnection.unregAssignmentRule(clusterId, serverId, ruleId); + public boolean unregAssignmentRule(UUID clusterId, UUID serverId, UUID ruleId) { + + LOGGER.debug( + "Unregistration assignment rule <{}>", //$NON-NLS-1$ + ruleId); + + if (!isConnected()) { + return false; + } + if (!checkAutenticateCluster(clusterId)) { + return false; + } + + try { + agentConnection.unregAssignmentRule(clusterId, serverId, ruleId); + } catch (Exception excp) { + LOGGER.error( + "Error unregistraion assignment rule", //$NON-NLS-1$ + excp); + return false; + } + + LOGGER.debug("Unregistration assignment rule <{}> succesful"); // $NON-NLS-1$ + + return true; } /** - * Gets an assignment rule description. + * Применяет ТНФ. * *

Требует аутентификации в кластере * * @param clusterId - ID кластера - * @param serverId - server ID - * @param ruleId - assignment rule ID - * @return assignment rule description + * @param mode - Режим применения ТНФ: 0 - частичное 1 - полное */ - public IAssignmentRuleInfo getAssignmentRuleInfo(UUID clusterId, UUID serverId, UUID ruleId) { - // TODO - return agentConnection.getAssignmentRuleInfo(clusterId, serverId, ruleId); + public boolean applyAssignmentRules(UUID clusterId, int mode) { + + LOGGER.debug( + "Apply assignment rules for cluster <{}>", //$NON-NLS-1$ + clusterId); + + if (!isConnected()) { + return false; + } + if (!checkAutenticateCluster(clusterId)) { + return false; + } + + try { + agentConnection.applyAssignmentRules(clusterId, mode); + } catch (Exception excp) { + LOGGER.error( + "Error apply assignment rules", //$NON-NLS-1$ + excp); + return false; + } + + LOGGER.debug("Apply assignment rules was succesful"); // $NON-NLS-1$ + + return true; } /** @@ -3630,4 +4042,45 @@ public List getResourceConsumptionCounterAccum return agentConnection.getResourceConsumptionCounterAccumulatedValues( clusterId, counterName, object); } + + /** + * Получить иконку с текущим состоянием сервера. + * + * @return Image - иконка текущего состояния сервера + */ + public Image getTreeImage() { + + Image icon; + + switch (serverState) { + case CONNECTED: + icon = connectedIcon; + break; + + case CONNECTING: + icon = connectingIcon; + break; + + case CONNECT_ERROR: + icon = connectErrorIcon; + break; + + case DISCONNECT: + default: + icon = defaultIcon; + break; + } + + return icon; + } + + /** + * Обновить элемент дерева сервера. + * + * @param serverItem - элемент дерева содержащий ссылку на Сервер + */ + public void updateTreeItemState(TreeItem serverItem) { + serverItem.setImage(getTreeImage()); + serverItem.setText(new String[] {getTreeTitle()}); + } } diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages.properties b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages.properties index 7a59c68..cfcd9a4 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages.properties +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages.properties @@ -2,6 +2,45 @@ #Eclipse messages class #Fri Oct 01 13:58:03 MSK 2021 +AssignmentRule.ApplicationExt = Value of additional parameter +AssignmentRule.InfoBaseName = Infobase name +AssignmentRule.Number = Number +AssignmentRule.ObjectType = Requirement object +AssignmentRule.ObjectType.AuxiliaryService = Utility cluster service +AssignmentRule.ObjectType.ClientTestingService = Testing service +AssignmentRule.ObjectType.Connection = Client infobase connection +AssignmentRule.ObjectType.CounterService = Service of resource consumption counters monitoring +AssignmentRule.ObjectType.DataAcceleratorService = Data accelerator service +AssignmentRule.ObjectType.DataBaseConfigurationUpdateService = Database configuration update service +AssignmentRule.ObjectType.DataEditLockService = Object locking service +AssignmentRule.ObjectType.DatabaseTableNumberingService = Table name and database field numbering service +AssignmentRule.ObjectType.DbCopiesService = Database copy service +AssignmentRule.ObjectType.DbCopiesTimeService = Database copy time service +AssignmentRule.ObjectType.EventLogService = Event logging service +AssignmentRule.ObjectType.ExternalDataSourceODBCService = ODBC external data source access service +AssignmentRule.ObjectType.ExternalDataSourceXMLAService = XMLA external data source access service +AssignmentRule.ObjectType.ExternalSessionManagerService = External session management service +AssignmentRule.ObjectType.ForAll = For all +AssignmentRule.ObjectType.FulltextSearchService = Full-text search service +AssignmentRule.ObjectType.GetSessionsService = Service for getting a session list +AssignmentRule.ObjectType.IntegrationDataService = Integration data service +AssignmentRule.ObjectType.JobService = Job service +AssignmentRule.ObjectType.LicenseService = Licensing service +AssignmentRule.ObjectType.NumerationService = Numbering service +AssignmentRule.ObjectType.OpenID2ProviderContextService = OpenID2 service provider +AssignmentRule.ObjectType.SessionDataService = Session data service +AssignmentRule.ObjectType.SessionReuseService = Session reuse service +AssignmentRule.ObjectType.SettingsService = User-defined settings service +AssignmentRule.ObjectType.TimestampService = Time service +AssignmentRule.ObjectType.TransactionLockService = Transaction lock service +AssignmentRule.Priority = Priority +AssignmentRule.RuleType = Requirement type +AssignmentRule.RuleType.Assign = Assign +AssignmentRule.RuleType.Auto = Auto +AssignmentRule.RuleType.DoNotAssign = Do not assign +AssignmentRule.TitleEditRule = Assignment rule +AssignmentRule.TitleNewRule = New assignment rule + ConnectionInfo.ConnectedAt = Connected at ConnectionInfo.Connection = Connection ConnectionInfo.Hostname = Hostname @@ -23,6 +62,7 @@ Server.Designer = Designer Server.JobScheduler = Job scheduler Server.LocalRasNotFound = Local RAS not found Server.LocalRasParamsIsEmpty = Local RAS path or port for Server %s is empty +Server.LocalRasParamsIsInvalid = To run RAS, you need to specify the platform version in the server connection settings.\r\nThe full version must be specified with the completed assembly number (the fourth block of digits).\r\nFor example, 8.3.13 is incorrect, 8.3.13.1690 is correct.\r\nThe current specified version is %s Server.NotConnect = not connect Server.TerminateSessionMessage = Your session was interrupted by the administrator Server.TheClusterAuthenticationError = The cluster autentication error. diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages_ru_RU.properties b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages_ru_RU.properties index 4da4f24..d712cfe 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages_ru_RU.properties +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibrary/messages_ru_RU.properties @@ -1,5 +1,44 @@ #Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/) +AssignmentRule.ApplicationExt = \u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0434\u043E\u043F. \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430 +AssignmentRule.InfoBaseName = \u0418\u043C\u044F \u0418\u0411 +AssignmentRule.Number = \u041D\u043E\u043C\u0435\u0440 +AssignmentRule.ObjectType = \u041E\u0431\u044A\u0435\u043A\u0442 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u044F +AssignmentRule.ObjectType.AuxiliaryService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0432\u0441\u043F\u043E\u043C\u043E\u0433\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u0444\u0443\u043D\u043A\u0446\u0438\u0439 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 +AssignmentRule.ObjectType.ClientTestingService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0442\u0435\u0441\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F +AssignmentRule.ObjectType.Connection = \u041A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0435 \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0441 \u0418\u0411 +AssignmentRule.ObjectType.CounterService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043C\u043E\u043D\u0438\u0442\u043E\u0440\u0438\u043D\u0433\u0430 \u0441\u0447\u0435\u0442\u0447\u0438\u043A\u043E\u0432 \u043F\u043E\u0442\u0440\u0435\u0431\u043B\u0435\u043D\u0438\u044F \u0440\u0435\u0441\u0443\u0440\u0441\u043E\u0432 +AssignmentRule.ObjectType.DataAcceleratorService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0414\u0430\u0442\u0430 a\u043A\u0441\u0435\u043B\u0435\u0440\u0430\u0442\u043E\u0440\u0430 +AssignmentRule.ObjectType.DataBaseConfigurationUpdateService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 +AssignmentRule.ObjectType.DataEditLockService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 +AssignmentRule.ObjectType.DatabaseTableNumberingService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043D\u043E\u043C\u0435\u0440\u043E\u0432 \u0438\u043C\u0435\u043D \u0442\u0430\u0431\u043B\u0438\u0446 \u0438 \u043F\u043E\u043B\u0435\u0439 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 +AssignmentRule.ObjectType.DbCopiesService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043A\u043E\u043F\u0438\u0439 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 +AssignmentRule.ObjectType.DbCopiesTimeService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u043A\u043E\u043F\u0438\u0439 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445 +AssignmentRule.ObjectType.EventLogService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0436\u0443\u0440\u043D\u0430\u043B\u043E\u0432 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 +AssignmentRule.ObjectType.ExternalDataSourceODBCService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0440\u0430\u0431\u043E\u0442\u044B \u0441 \u0432\u043D\u0435\u0448\u043D\u0438\u043C\u0438 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u043C\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u0447\u0435\u0440\u0435\u0437 ODBC +AssignmentRule.ObjectType.ExternalDataSourceXMLAService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0440\u0430\u0431\u043E\u0442\u044B \u0441 \u0432\u043D\u0435\u0448\u043D\u0438\u043C\u0438 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u043C\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 \u0447\u0435\u0440\u0435\u0437 XMLA +AssignmentRule.ObjectType.ExternalSessionManagerService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0432\u043D\u0435\u0448\u043D\u0435\u0433\u043E \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0441\u0435\u0430\u043D\u0441\u0430\u043C\u0438 +AssignmentRule.ObjectType.ForAll = \u0414\u043B\u044F \u0432\u0441\u0435\u0445 +AssignmentRule.ObjectType.FulltextSearchService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E \u043F\u043E\u0438\u0441\u043A\u0430 +AssignmentRule.ObjectType.GetSessionsService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F \u0441\u043F\u0438\u0441\u043A\u0430 \u0441\u0435\u0430\u043D\u0441\u043E\u0432 +AssignmentRule.ObjectType.IntegrationDataService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0438\u043D\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043E\u043D\u043D\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 +AssignmentRule.ObjectType.JobService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u0434\u0430\u043D\u0438\u0439 +AssignmentRule.ObjectType.LicenseService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F +AssignmentRule.ObjectType.NumerationService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043D\u0443\u043C\u0435\u0440\u0430\u0446\u0438\u0438 +AssignmentRule.ObjectType.OpenID2ProviderContextService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043F\u0440\u043E\u0432\u0430\u0439\u0434\u0435\u0440\u0430 OpenID2 +AssignmentRule.ObjectType.SessionDataService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0441\u0435\u0430\u043D\u0441\u043E\u0432\u044B\u0445 \u0434\u0430\u043D\u043D\u044B\u0445 +AssignmentRule.ObjectType.SessionReuseService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u0433\u043E \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F \u0441\u0435\u0430\u043D\u0441\u043E\u0432 +AssignmentRule.ObjectType.SettingsService = \u0421\u0435\u0440\u0432\u0438\u0441 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A +AssignmentRule.ObjectType.TimestampService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 +AssignmentRule.ObjectType.TransactionLockService = \u0421\u0435\u0440\u0432\u0438\u0441 \u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u043E\u043D\u043D\u044B\u0445 \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043E\u043A +AssignmentRule.Priority = \u041F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442 +AssignmentRule.RuleType = \u0422\u0438\u043F \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u044F +AssignmentRule.RuleType.Assign = \u041D\u0430\u0437\u043D\u0430\u0447\u0430\u0442\u044C +AssignmentRule.RuleType.Auto = \u0410\u0432\u0442\u043E +AssignmentRule.RuleType.DoNotAssign = \u041D\u0435 \u043D\u0430\u0437\u043D\u0430\u0447\u0430\u0442\u044C +AssignmentRule.TitleEditRule = \u0422\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u0435 \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u043E\u0441\u0442\u0438 +AssignmentRule.TitleNewRule = \u041D\u043E\u0432\u043E\u0435 \u0442\u0440\u0435\u0431\u043E\u0432\u0430\u043D\u0438\u0435 \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u043E\u0441\u0442\u0438 + ConnectionInfo.ConnectedAt = \u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u043E \u0441 ConnectionInfo.Connection = \u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 ConnectionInfo.Hostname = \u0418\u043C\u044F \u0445\u043E\u0441\u0442\u0430 @@ -20,7 +59,8 @@ Server.ClusterConsole = \u041A\u043E\u043D\u0441\u04 Server.Designer = \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440 Server.JobScheduler = \u041F\u043B\u0430\u043D\u0438\u0440\u043E\u0432\u0449\u0438\u043A \u0437\u0430\u0434\u0430\u043D\u0438\u0439 Server.LocalRasNotFound = \u041D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D \u0438\u0441\u043F\u043E\u043B\u043D\u044F\u0435\u043C\u044B\u0439 \u0444\u0430\u0439\u043B \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E RAS -Server.LocalRasParamsIsEmpty = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E RAS \u043D\u0435 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u044B +Server.LocalRasParamsIsEmpty = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u0433\u043E RAS \u0434\u043B\u044F \u0441\u0435\u0440\u0432\u0435\u0440\u0430 %s \u043D\u0435 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u044B +Server.LocalRasParamsIsInvalid = \u0414\u043B\u044F \u0437\u0430\u043F\u0443\u0441\u043A\u0430 RAS \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0443\u0442\u043E\u0447\u043D\u0438\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F \u043A \u0441\u0435\u0440\u0432\u0435\u0440\u0443.\r\n\u0414\u043E\u043B\u0436\u043D\u0430 \u0431\u044B\u0442\u044C \u0443\u043A\u0430\u0437\u0430\u043D\u0430 \u043F\u043E\u043B\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0441 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043D\u044B\u043C \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0441\u0431\u043E\u0440\u043A\u0438 (\u0447\u0435\u0442\u0432\u0435\u0440\u0442\u044B\u0439 \u0431\u043B\u043E\u043A \u0446\u044B\u0444\u0440).\r\n\u041D\u0430\u043F\u0440\u0438\u043C\u0435\u0440, 8.3.13 - \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E, 8.3.13.1690 - \u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E.\r\n\u0422\u0435\u043A\u0443\u0449\u0430\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F - %s Server.NotConnect = \u043D\u0435 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D Server.TerminateSessionMessage = \u0412\u0430\u0448 \u0441\u0435\u0430\u043D\u0441 \u0431\u044B\u043B \u043F\u0440\u0435\u0440\u0432\u0430\u043D \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u043E\u043C Server.TheClusterAuthenticationError = \u041E\u0448\u0438\u0431\u043A\u0430 \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0438 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430. diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AboutDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AboutDialog.java index ab0af08..b744585 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AboutDialog.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AboutDialog.java @@ -17,6 +17,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.wb.swt.SWTResourceManager; import ru.yanygin.clusterAdminLibrary.Config; +import ru.yanygin.clusterAdminLibrary.Helper; /** Диалог "О программе". */ public class AboutDialog extends Dialog { @@ -91,6 +92,10 @@ protected Control createDialogArea(Composite parent) { linkEmail.setText(Strings.EMAIL_DESCRIPTION); linkEmail.addSelectionListener(goToLinkListener); + Link linkBoosty = new Link(container, 0); + linkBoosty.setText(Strings.BOOSTY_DESCRIPTION); + linkBoosty.addSelectionListener(goToLinkListener); + return container; } @@ -166,6 +171,8 @@ private static class Strings { String.format(getString("Telegram_Description"), TELEGRAM_LINK); static final String EMAIL_DESCRIPTION = String.format(getString("Email_Description"), EMAIL_LINK); + static final String BOOSTY_DESCRIPTION = + String.format(getString("Boosty_Description"), Helper.BOOSTY_LINK); static String getString(String key) { return Messages.getString("AboutDialog." + key); //$NON-NLS-1$ @@ -174,6 +181,6 @@ static String getString(String key) { @Override protected Point getInitialSize() { - return new Point(500, 380); + return new Point(500, 418); } } diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AdminEditDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AdminEditDialog.java new file mode 100644 index 0000000..1d3c845 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AdminEditDialog.java @@ -0,0 +1,263 @@ +package ru.yanygin.clusterAdminLibraryUI; + +import com._1c.v8.ibis.admin.IRegUserInfo; +import com._1c.v8.ibis.admin.RegUserInfo; +import java.util.UUID; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import ru.yanygin.clusterAdminLibrary.Helper; +import ru.yanygin.clusterAdminLibrary.Server; + +/** Диалог редактирования администратора. */ +public class AdminEditDialog extends Dialog { + + private Server server; + private UUID clusterId; + private IRegUserInfo userInfo; + + private Text txtUsername; + private Text txtPassword; + private Text txtPasswordConfirm; + private Text txtSysUsername; + private Text txtDescription; + private Button btnPasswordAuthAllowed; + private Button btnSysAuthAllowed; + + private boolean passIsModified = false; + + /** + * Создание диалога редактирования администратора. + * + * @param parentShell - parent shell + * @param server - Сервер + * @param clusterId - ID кластера + * @param userInfo - IRegUserInfo пользователя + * @wbp.parser.constructor + */ + public AdminEditDialog(Shell parentShell, Server server, UUID clusterId, IRegUserInfo userInfo) { + super(parentShell); + setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + + this.server = server; + this.clusterId = clusterId; + this.userInfo = userInfo; + } + + @Override + protected void configureShell(Shell newShell) { + newShell.setMinimumSize(new Point(300, 39)); + super.configureShell(newShell); + + if (userInfo == null) { + newShell.setText(clusterId == null ? Strings.TITLE_SERVER_NEW : Strings.TITLE_CLUSTER_NEW); + } else { + newShell.setText(clusterId == null ? Strings.TITLE_SERVER_EDIT : Strings.TITLE_CLUSTER_EDIT); + } + } + + /** + * Create contents of the dialog. + * + * @param parent - parent composite + */ + @Override + protected Control createDialogArea(Composite parent) { + + Composite container = (Composite) super.createDialogArea(parent); + GridLayout gridLayout = (GridLayout) container.getLayout(); + gridLayout.numColumns = 2; + + Label lblUsername = new Label(container, SWT.NONE); + lblUsername.setText(Strings.NAME); + + txtUsername = new Text(container, SWT.BORDER); + txtUsername.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Label lblDescription = new Label(container, SWT.NONE); + lblDescription.setText(Strings.DESCRIPTION); + + txtDescription = new Text(container, SWT.BORDER); + txtDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + btnPasswordAuthAllowed = new Button(container, SWT.CHECK); + btnPasswordAuthAllowed.setText(Strings.PASSWORD_AUTH_ALLOWED); + btnPasswordAuthAllowed.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + txtPassword.setEditable(btnPasswordAuthAllowed.getSelection()); + txtPasswordConfirm.setEditable(btnPasswordAuthAllowed.getSelection()); + } + }); + + new Label(container, SWT.NONE); + + Label lblPassword = new Label(container, SWT.NONE); + lblPassword.setText(Strings.PASSWORD); + + txtPassword = new Text(container, SWT.BORDER | SWT.PASSWORD); + txtPassword.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + + Label lblPasswordConfirm = new Label(container, SWT.NONE); + lblPasswordConfirm.setText(Strings.PASSWORD_CONFIRM); + + txtPasswordConfirm = new Text(container, SWT.BORDER | SWT.PASSWORD); + txtPasswordConfirm.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + + btnSysAuthAllowed = new Button(container, SWT.CHECK); + btnSysAuthAllowed.setText(Strings.SYS_AUTH_ALLOWED); + btnSysAuthAllowed.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + txtSysUsername.setEditable(btnSysAuthAllowed.getSelection()); + } + }); + + new Label(container, SWT.NONE); + + Label lblSysUsername = new Label(container, SWT.NONE); + lblSysUsername.setText(Strings.SYS_USERNAME); + + txtSysUsername = new Text(container, SWT.BORDER); + txtSysUsername.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + initProperties(); + + parent.pack(); + + return container; + } + + /** + * Получает итоговую информацию об администраторе. + * + * @return IRegUserInfo информация об администраторе + */ + public IRegUserInfo getUserinfo() { + return userInfo; + } + + private void initProperties() { + if (userInfo != null) { + this.txtUsername.setText(userInfo.getName()); + this.txtDescription.setText(userInfo.getDescr()); + + this.btnPasswordAuthAllowed.setSelection(userInfo.isPasswordAuthAllowed()); + this.txtPassword.setText(userInfo.getPassword()); + this.txtPasswordConfirm.setText(userInfo.getPassword()); + + this.btnSysAuthAllowed.setSelection(userInfo.isSysAuthAllowed()); + this.txtSysUsername.setText(userInfo.getSysUserName()); + } + + txtPassword.addModifyListener( + new ModifyListener() { + public void modifyText(ModifyEvent e) { + passIsModified = true; + } + }); + txtPasswordConfirm.addModifyListener( + new ModifyListener() { + public void modifyText(ModifyEvent e) { + passIsModified = true; + } + }); + txtPassword.setEditable(btnPasswordAuthAllowed.getSelection()); + txtPasswordConfirm.setEditable(btnPasswordAuthAllowed.getSelection()); + txtSysUsername.setEditable(btnSysAuthAllowed.getSelection()); + } + + private boolean regClusterAdmin() { + if (passIsModified && !txtPassword.getText().equals(txtPasswordConfirm.getText())) { + Helper.showMessageBox(Strings.PASSWORDS_NOT_MATCH); + return false; + } + + if (userInfo == null) { + userInfo = + new RegUserInfo( + txtUsername.getText(), + txtDescription.getText(), + txtPassword.getText(), + btnPasswordAuthAllowed.getSelection(), + btnSysAuthAllowed.getSelection(), + txtSysUsername.getText()); + } else { + + userInfo.setName(txtUsername.getText()); + userInfo.setDescr(txtDescription.getText()); + + userInfo.setSysAuthAllowed(btnPasswordAuthAllowed.getSelection()); + userInfo.setPassword(txtPassword.getText()); + + userInfo.setSysAuthAllowed(btnSysAuthAllowed.getSelection()); + userInfo.setSysUserName(txtSysUsername.getText()); + } + + boolean unregOk = + clusterId == null + ? server.regAgentAdmin(userInfo) + : server.regClusterAdmin(clusterId, userInfo); + + return unregOk; + } + + /** + * Create contents of the button bar. + * + * @param parent - parent composite + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + Button button = + createButton(parent, IDialogConstants.FINISH_ID, IDialogConstants.OK_LABEL, true); + button.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (regClusterAdmin()) { + close(); + } + } + }); + + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + private static class Strings { + + static final String TITLE_CLUSTER_EDIT = getString("TitleClusterEdit"); + static final String TITLE_CLUSTER_NEW = getString("TitleClusterNew"); + static final String TITLE_SERVER_EDIT = getString("TitleServerEdit"); + static final String TITLE_SERVER_NEW = getString("TitleServerNew"); + + static final String NAME = getString("Name"); + static final String DESCRIPTION = getString("Description"); + static final String PASSWORD_AUTH_ALLOWED = getString("PasswordAuthAllowed"); + static final String PASSWORD = getString("Password"); + static final String PASSWORD_CONFIRM = getString("PasswordConfirm"); + static final String SYS_AUTH_ALLOWED = getString("SysAuthAllowed"); + static final String SYS_USERNAME = getString("SysUsername"); + + static final String PASSWORDS_NOT_MATCH = getString("PasswordsNotMatch"); + + static String getString(String key) { + return Messages.getString("AdminDialog." + key); // $NON-NLS-1$ + } + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AdminsDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AdminsDialog.java new file mode 100644 index 0000000..923d411 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AdminsDialog.java @@ -0,0 +1,331 @@ +package ru.yanygin.clusterAdminLibraryUI; + +import com._1c.v8.ibis.admin.IRegUserInfo; +import java.util.List; +import java.util.UUID; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.ToolBar; +import org.eclipse.swt.widgets.ToolItem; +import ru.yanygin.clusterAdminLibrary.Helper; +import ru.yanygin.clusterAdminLibrary.Server; + +/** Диалог редактирования администратора. */ +public class AdminsDialog extends Dialog { + + private Server server; + private UUID clusterId; + + private Table tableAdmins; + + final Image addIcon16 = Helper.getImage("add_16.png"); // $NON-NLS-1$ + final Image editIcon16 = Helper.getImage("edit_16.png"); // $NON-NLS-1$ + final Image deleteIcon16 = Helper.getImage("delete_16.png"); // $NON-NLS-1$ + + /** + * Create the dialog. + * + * @param parentShell - parent shell + * @param server - server params + * @param clusterId - Id кластера + */ + public AdminsDialog(Shell parentShell, Server server, UUID clusterId) { + super(parentShell); + setShellStyle(SWT.DIALOG_TRIM); + + this.server = server; + this.clusterId = clusterId; + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(Strings.TITLE_WINDOW); + } + + /** + * Create contents of the dialog. + * + * @param parent - parent composite + */ + @Override + protected Control createDialogArea(Composite parent) { + + Composite container = (Composite) super.createDialogArea(parent); + + ToolBar toolBar = new ToolBar(container, SWT.FLAT | SWT.RIGHT); + + ToolItem toolBarAdd = new ToolItem(toolBar, SWT.NONE); + toolBarAdd.setImage(addIcon16); + toolBarAdd.setText(Strings.TOOLBAR_ADD); + toolBarAdd.addSelectionListener(addAdminListener); + + ToolItem toolBarEdit = new ToolItem(toolBar, SWT.NONE); + toolBarEdit.setImage(editIcon16); + toolBarEdit.setText(Strings.TOOLBAR_EDIT); + toolBarEdit.addSelectionListener(editAdminListener); + + ToolItem toolBarDelete = new ToolItem(toolBar, SWT.NONE); + toolBarDelete.setImage(deleteIcon16); + toolBarDelete.setText(Strings.TOOLBAR_DELETE); + toolBarDelete.addSelectionListener(delAdminListener); + + tableAdmins = new Table(container, SWT.BORDER | SWT.CHECK | SWT.FULL_SELECTION | SWT.MULTI); + tableAdmins.setHeaderVisible(true); + tableAdmins.setLinesVisible(true); + tableAdmins.addKeyListener(keyPressListener); + tableAdmins.addMouseListener(mouseDoubleClickListener); + + TableColumn tcName = new TableColumn(tableAdmins, SWT.NONE); + tcName.setWidth(120); + tcName.setText(Strings.NAME); + + TableColumn tcDescr = new TableColumn(tableAdmins, SWT.NONE); + tcDescr.setWidth(150); + tcDescr.setText(Strings.DESCRIPTION); + + TableColumn tcPasswordAuthAllowed = new TableColumn(tableAdmins, SWT.NONE); + tcPasswordAuthAllowed.setWidth(110); + tcPasswordAuthAllowed.setText(Strings.PASSWORD_AUTH_ALLOWED); + + TableColumn tcSysAuthAllowed = new TableColumn(tableAdmins, SWT.NONE); + tcSysAuthAllowed.setWidth(80); + tcSysAuthAllowed.setText(Strings.SYS_AUTH_ALLOWED); + + TableColumn tcSysUsername = new TableColumn(tableAdmins, SWT.NONE); + tcSysUsername.setWidth(120); + tcSysUsername.setText(Strings.SYS_USERNAME); + + initContextMenu(); + initProperties(); + + parent.pack(); + + return container; + } + + private void initContextMenu() { + Menu tableMenu = new Menu(tableAdmins); + tableAdmins.setMenu(tableMenu); + // установить активность контекстного меню + + MenuItem addMenuItem = new MenuItem(tableMenu, SWT.NONE); + addMenuItem.setText(Strings.CONTEXT_MENU_ADD); + addMenuItem.setImage(addIcon16); + addMenuItem.addSelectionListener(addAdminListener); + + MenuItem editMenuItem = new MenuItem(tableMenu, SWT.NONE); + editMenuItem.setText(Strings.CONTEXT_MENU_EDIT); + editMenuItem.setImage(editIcon16); + editMenuItem.addSelectionListener(editAdminListener); + + MenuItem delMenuItem = new MenuItem(tableMenu, SWT.NONE); + delMenuItem.setText(Strings.CONTEXT_MENU_DELETE); + delMenuItem.setImage(deleteIcon16); + delMenuItem.addSelectionListener(delAdminListener); + } + + private void initProperties() { + if (server != null) { + fillTableAdmins(); + } + } + + private void fillTableAdmins() { + + tableAdmins.removeAll(); + List admins = + clusterId == null ? server.getAgentAdmins() : server.getClusterAdmins(clusterId); + + admins.forEach( + (userInfo) -> { + TableItem adminItem = new TableItem(tableAdmins, SWT.NONE); + adminItem.setText(getTableAdminsItemText(userInfo)); + adminItem.setData(userInfo); + }); + tableAdmins.pack(); + } + + private String[] getTableAdminsItemText(IRegUserInfo userInfo) { + return new String[] { + userInfo.getName(), + userInfo.getDescr(), + String.valueOf(userInfo.isPasswordAuthAllowed()), + String.valueOf(userInfo.isSysAuthAllowed()), + userInfo.getSysUserName() + }; + } + + /** + * Create contents of the button bar. + * + * @param parent - parent composite + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + Button button = + createButton(parent, IDialogConstants.CLOSE_ID, IDialogConstants.CLOSE_LABEL, true); + button.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + }); + } + + private KeyAdapter keyPressListener = + new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + switch (e.keyCode) { + case SWT.INSERT: + addAdmin(); + break; + + case SWT.F2: + editAdmin(); + break; + + case SWT.DEL: + delAdmin(); + break; + + default: + break; + } + } + }; + + private MouseAdapter mouseDoubleClickListener = + new MouseAdapter() { + @Override + public void mouseDoubleClick(MouseEvent e) { + editAdmin(); + } + }; + + private SelectionAdapter addAdminListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + addAdmin(); + } + }; + + private SelectionAdapter editAdminListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + editAdmin(); + } + }; + + private SelectionAdapter delAdminListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + delAdmin(); + } + }; + + private void addAdmin() { + + AdminEditDialog adminEditDialog = + new AdminEditDialog(Display.getDefault().getActiveShell(), server, clusterId, null); + + if (adminEditDialog.open() == 0) { + IRegUserInfo userInfo = adminEditDialog.getUserinfo(); + + TableItem adminItem = new TableItem(tableAdmins, SWT.NONE); + adminItem.setText(getTableAdminsItemText(userInfo)); + adminItem.setData(userInfo); + getShell().pack(); + } + } + + private void editAdmin() { + TableItem[] admins = tableAdmins.getSelection(); + if (admins.length == 0) { + return; + } + + TableItem adminItem = admins[0]; + + IRegUserInfo userInfo = (IRegUserInfo) adminItem.getData(); + + AdminEditDialog adminEditDialog = + new AdminEditDialog(Display.getDefault().getActiveShell(), server, clusterId, userInfo); + + if (adminEditDialog.open() == 0) { + userInfo = adminEditDialog.getUserinfo(); + adminItem.setText(getTableAdminsItemText(userInfo)); + adminItem.setData(userInfo); + } + } + + private void delAdmin() { + TableItem[] admins = tableAdmins.getSelection(); + if (admins.length == 0) { + return; + } + + int answer = Helper.showQuestionBox(Strings.ANSWER_DELETE); + if (answer == SWT.YES) { + for (TableItem adminItem : admins) { + + IRegUserInfo userInfo = (IRegUserInfo) adminItem.getData(); + boolean unregOk = + clusterId == null + ? server.unregAgentAdmin(userInfo.getName()) + : server.unregClusterAdmin(clusterId, userInfo.getName()); + + if (unregOk) { + adminItem.dispose(); + } + } + getShell().pack(); + } + } + + private static class Strings { + + static final String TITLE_WINDOW = getString("TitleList"); + static final String NAME = getString("Name"); + static final String DESCRIPTION = getString("Description"); + static final String PASSWORD_AUTH_ALLOWED = getString("PasswordAuthAllowed"); + static final String SYS_AUTH_ALLOWED = getString("SysAuthAllowed"); + static final String SYS_USERNAME = getString("SysUsername"); + + static final String ANSWER_DELETE = getString("AnswerDelete"); + + static final String TOOLBAR_ADD = Messages.getString("ViewerArea.ContextMenu.Add"); + static final String TOOLBAR_EDIT = Messages.getString("ViewerArea.ContextMenu.Edit"); + static final String TOOLBAR_DELETE = Messages.getString("ViewerArea.ContextMenu.Delete"); + static final String CONTEXT_MENU_ADD = TOOLBAR_ADD.concat("\tIns"); + static final String CONTEXT_MENU_EDIT = TOOLBAR_EDIT.concat("\tF2"); + static final String CONTEXT_MENU_DELETE = TOOLBAR_DELETE.concat("\tDel"); + + static String getString(String key) { + return Messages.getString("AdminDialog." + key); + } + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AssignmentRuleDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AssignmentRuleDialog.java new file mode 100644 index 0000000..570f068 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/AssignmentRuleDialog.java @@ -0,0 +1,264 @@ +package ru.yanygin.clusterAdminLibraryUI; + +import com._1c.v8.ibis.admin.AssignmentRuleInfo; +import com._1c.v8.ibis.admin.IAssignmentRuleInfo; +import java.util.UUID; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Spinner; +import ru.yanygin.clusterAdminLibrary.AssignmentRuleContentProvider; +import ru.yanygin.clusterAdminLibrary.AssignmentRuleLabelProvider; +import ru.yanygin.clusterAdminLibrary.Messages; +import ru.yanygin.clusterAdminLibrary.Server; + +/** Диалог редактирования ТНФ. */ +public class AssignmentRuleDialog extends Dialog { + + private Server server; + private UUID clusterId; + private UUID wsId; + private IAssignmentRuleInfo ruleInfo; + + private Combo txtObjectType; + private Combo txtInfoBaseName; + private Combo txtApplicationExt; + + private Button btnRuleTypeAuto; + private Button btnRuleTypeAssign; + private Button btnRuleTypeDoNotAssign; + private Spinner spinnerPriority; + private Spinner spinnerNumber; + + /** + * Создание диалога редактирования ТНФ. + * + * @param parentShell - parent shell + * @param server - Сервер + * @param clusterId - ID кластера + * @param ruleInfo - IAssignmentRuleInfo правило ТНФ + * @wbp.parser.constructor + */ + public AssignmentRuleDialog( + Shell parentShell, Server server, UUID clusterId, UUID wsId, IAssignmentRuleInfo ruleInfo) { + super(parentShell); + setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + + this.server = server; + this.clusterId = clusterId; + this.wsId = wsId; + this.ruleInfo = ruleInfo; + } + + @Override + protected void configureShell(Shell newShell) { + newShell.setMinimumSize(new Point(300, 39)); + super.configureShell(newShell); + + if (ruleInfo == null) { + newShell.setText(Strings.TITLE_NEW_RULE); + } else { + newShell.setText(Strings.TITLE_EDIT_RULE); + } + } + + /** + * Create contents of the dialog. + * + * @param parent - parent composite + */ + @Override + protected Control createDialogArea(Composite parent) { + + Composite container = (Composite) super.createDialogArea(parent); + GridLayout gridLayout = (GridLayout) container.getLayout(); + gridLayout.numColumns = 2; + + Label lblObjectType = new Label(container, SWT.NONE); + lblObjectType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblObjectType.setText(Strings.OBJECT_TYPE); + + txtObjectType = new Combo(container, SWT.READ_ONLY); + txtObjectType.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Label lblRuleType = new Label(container, SWT.NONE); + lblRuleType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblRuleType.setText(Strings.RULE_TYPE); + + Composite composite = new Composite(container, SWT.NONE); + composite.setLayout(new RowLayout(SWT.HORIZONTAL)); + + btnRuleTypeAuto = new Button(composite, SWT.RADIO); + btnRuleTypeAuto.setText(AssignmentRuleLabelProvider.RULE_TYPE_AUTO); + + btnRuleTypeAssign = new Button(composite, SWT.RADIO); + btnRuleTypeAssign.setText(AssignmentRuleLabelProvider.RULE_TYPE_ASSIGN); + + btnRuleTypeDoNotAssign = new Button(composite, SWT.RADIO); + btnRuleTypeDoNotAssign.setText(AssignmentRuleLabelProvider.RULE_TYPE_DO_NOT_ASSIGN); + + Label lblInfoBaseName = new Label(container, SWT.NONE); + lblInfoBaseName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblInfoBaseName.setText(Strings.INFOBASE_NAME); + + txtInfoBaseName = new Combo(container, SWT.BORDER); + txtInfoBaseName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + + Label lblApplicationExt = new Label(container, SWT.NONE); + lblApplicationExt.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblApplicationExt.setText(Strings.APPLICATION_EXT); + + txtApplicationExt = new Combo(container, SWT.BORDER); + GridData gdTxtApplicationExt = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); + gdTxtApplicationExt.widthHint = 100; + txtApplicationExt.setLayoutData(gdTxtApplicationExt); + + Label lblNumber = new Label(container, SWT.NONE); + lblNumber.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblNumber.setText(Strings.NUMBER); + + spinnerNumber = new Spinner(container, SWT.BORDER); + spinnerNumber.setMinimum(1); + spinnerNumber.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + + Label lblPriority = new Label(container, SWT.NONE); + lblPriority.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblPriority.setText(Strings.PRIORITY); + + spinnerPriority = new Spinner(container, SWT.BORDER); + spinnerPriority.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); + + fillComboFields(); + initValueFields(); + + parent.pack(); + + return container; + } + + private void fillComboFields() { + // Заполнение выпадающих списков значениями для выбора + AssignmentRuleLabelProvider.getObjectTypes() + .forEach( + (k, v) -> { + txtObjectType.add(v); + txtObjectType.setData(v, k); + }); + + server.getInfoBasesShort(clusterId).forEach(ib -> txtInfoBaseName.add(ib.getName())); + + String[] appExtValues = AssignmentRuleLabelProvider.getApplicationExtValues(); + for (String v : appExtValues) { + txtApplicationExt.add(v); + txtApplicationExt.setData(v); + } + } + + private void initValueFields() { + if (ruleInfo != null) { + this.txtObjectType.setText( + AssignmentRuleLabelProvider.getObjectType(ruleInfo.getObjectType())); + + final int ruleType = ruleInfo.getRuleType(); + this.btnRuleTypeAuto.setSelection(ruleType == 1); + this.btnRuleTypeAssign.setSelection(ruleType == 2); + this.btnRuleTypeDoNotAssign.setSelection(ruleType == 0); + + this.txtInfoBaseName.setText(ruleInfo.getInfoBaseName()); + this.txtApplicationExt.setText(ruleInfo.getApplicationExt()); + + this.spinnerPriority.setSelection(ruleInfo.getPriority()); + this.spinnerNumber.setSelection(AssignmentRuleContentProvider.getRuleNumber(ruleInfo)); + } else { + this.txtObjectType.setText(AssignmentRuleLabelProvider.getObjectType("")); + this.btnRuleTypeAuto.setSelection(true); + } + } + + private boolean regRule() { + + if (ruleInfo == null) { + ruleInfo = new AssignmentRuleInfo(); + } + + String objectType = (String) txtObjectType.getData(txtObjectType.getText()); + ruleInfo.setObjectType(objectType); + + final int ruleType; + if (btnRuleTypeAuto.getSelection()) { + ruleType = 1; + } else if (btnRuleTypeAssign.getSelection()) { + ruleType = 2; + } else { + ruleType = 0; + } + ruleInfo.setRuleType(ruleType); + + ruleInfo.setInfoBaseName(txtInfoBaseName.getText()); + ruleInfo.setApplicationExt(txtApplicationExt.getText()); + + ruleInfo.setPriority(spinnerPriority.getSelection()); + + return server.regAssignmentRule(clusterId, wsId, ruleInfo, spinnerNumber.getSelection() - 1); + } + + /** + * Получает итоговую информацию о правиле ТНФ. + * + * @return IAssignmentRuleInfo правило ТНФ + */ + public IAssignmentRuleInfo getRuleInfo() { + return ruleInfo; + } + + /** + * Create contents of the button bar. + * + * @param parent - parent composite + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + Button button = + createButton(parent, IDialogConstants.FINISH_ID, IDialogConstants.OK_LABEL, true); + button.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (regRule()) { + close(); + } + } + }); + + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + private static class Strings { + + static final String TITLE_EDIT_RULE = getString("TitleEditRule"); + static final String TITLE_NEW_RULE = getString("TitleNewRule"); + + static final String NUMBER = getString("Number"); + static final String OBJECT_TYPE = getString("ObjectType"); + static final String RULE_TYPE = getString("RuleType"); + static final String INFOBASE_NAME = getString("InfoBaseName"); + static final String APPLICATION_EXT = getString("ApplicationExt"); + static final String PRIORITY = getString("Priority"); + + static String getString(String key) { + return Messages.getString("AssignmentRule." + key); // $NON-NLS-1$ + } + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/BackgroundTaskParams.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/BackgroundTaskParams.java new file mode 100644 index 0000000..e2b2a47 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/BackgroundTaskParams.java @@ -0,0 +1,352 @@ +package ru.yanygin.clusterAdminLibraryUI; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ComboBoxCellEditor; +import org.eclipse.jface.viewers.DialogCellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TextCellEditor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CCombo; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import ru.yanygin.clusterAdminLibrary.BackgroundTask; +import ru.yanygin.clusterAdminLibrary.UserPassPair; + +/** Диалог параметров фоновой задачи. */ +public class BackgroundTaskParams extends Dialog { + + private static final String USERNAME_TITLE = "v8username"; + private static final String PASSWORD_TITLE = "v8password"; + + private Map params; + private BackgroundTask task; + private String title; + private Table tableParams; + private Map infobasesCredentials = new HashMap<>(); + private List usernames = new ArrayList<>(); + private String currentUsernameValue = ""; + private String currentFilenameExt = ""; + private String currentFilepath = ""; + + /** + * Создание диалога ввода имени пользователя и пароля. + * + * @param parentShell - parent shell + * @param params - текущие имя пользователя и пароль + * @param task - ссылка на объект задачи + * @param infobasesCredentials - данные доступа к инфобазам + */ + public BackgroundTaskParams( + Shell parentShell, + Map params, + BackgroundTask task, + List infobasesCredentials) { + super(parentShell); + setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); + + this.params = params; + this.task = task; + this.title = task.getScriptName(); + + infobasesCredentials.forEach( + up -> { + this.infobasesCredentials.put(up.getUsername(), up.getPassword()); + this.usernames.add(up.getUsername()); + }); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(Strings.TITLE_WINDOW + this.title); + } + + /** + * Create contents of the dialog. + * + * @param parent - parent composite + */ + @Override + protected Control createDialogArea(Composite parent) { + + Composite container = (Composite) super.createDialogArea(parent); + + TableViewer tableViewer = new TableViewer(container, SWT.BORDER | SWT.FULL_SELECTION); + tableParams = tableViewer.getTable(); + tableParams.setLinesVisible(true); + tableParams.setHeaderVisible(true); + tableParams.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + + tableViewer.setContentProvider(new ParamsContentProvider()); + + TableViewerColumn tableViewerColumnParamKey = new TableViewerColumn(tableViewer, SWT.NONE); + TableColumn clmnParamKey = tableViewerColumnParamKey.getColumn(); + clmnParamKey.setMoveable(true); + clmnParamKey.setWidth(120); + clmnParamKey.setText(Strings.TITLE_PARAMNAME); + // tableViewerColumnParamKey.setEditingSupport(new + // TableViewerEditingSupport(tableViewer)); + tableViewerColumnParamKey.setLabelProvider( + new ColumnLabelProvider() { + @Override + public String getText(Object element) { + String[] p = (String[]) element; + return p[0]; + } + }); + + TableViewerColumn tableViewerColumnParamValue = new TableViewerColumn(tableViewer, SWT.NONE); + TableColumn clmnParamValue = tableViewerColumnParamValue.getColumn(); + clmnParamValue.setMoveable(true); + clmnParamValue.setWidth(280); + clmnParamValue.setText(Strings.TITLE_PARAMVALUE); + tableViewerColumnParamValue.setEditingSupport(new TableViewerEditingSupport(tableViewer)); + tableViewerColumnParamValue.setLabelProvider( + new ColumnLabelProvider() { + @Override + public String getText(Object element) { + String[] p = (String[]) element; + return p[1]; + } + }); + tableViewer.setInput(params); + + return container; + } + + /** + * Возвращает заполненные пользователем параметры запуска задачи. + * + * @return параметры запуска задачи + */ + public Map getParams() { + return params; + } + + /** Экранирокание имени пользователя и пароля. */ + private void checkUsernameParam() { + String user = params.get(USERNAME_TITLE); + + if (Objects.nonNull(user)) { + params.put(USERNAME_TITLE, "\"" + params.get(USERNAME_TITLE) + "\""); + params.put(PASSWORD_TITLE, "\"" + params.get(PASSWORD_TITLE) + "\""); + } + } + + /** + * Create contents of the button bar. + * + * @param parent - parent composite + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + Button button = + createButton(parent, IDialogConstants.FINISH_ID, IDialogConstants.OK_LABEL, true); + button.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + checkUsernameParam(); + close(); + } + }); + + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + protected boolean isUsernameParam(String e) { + return e.equals(USERNAME_TITLE); + } + + protected boolean isPasswordParam(String e) { + return e.equals(PASSWORD_TITLE); + } + + protected boolean isFilepathParam(String[] e) { + if (task.isFilepathParam(e[0])) { + currentFilenameExt = task.getFilenameFilterExt(); + currentFilepath = e[1]; + return true; + } + return false; + } + + class TableViewerEditingSupport extends EditingSupport { + + private TableViewer viewer; + private TextCellEditor textEditor; + private ComboBoxCellEditor usernameEditor; + private DialogCellEditor filenameEditor; + + public TableViewerEditingSupport(TableViewer viewer) { + super(viewer); + textEditor = new TextCellEditor(viewer.getTable(), SWT.BORDER); + + usernameEditor = + new ComboBoxCellEditor( + viewer.getTable(), usernames.toArray(new String[0]), SWT.SINGLE | SWT.BORDER); + + filenameEditor = + new DialogCellEditor(viewer.getTable()) { + @Override + protected Object openDialogBox(Control cellEditorWindow) { + + final String[] filterNames = {String.format(Strings.FILTER_NAME, currentFilenameExt)}; + final String[] filterExt = {currentFilenameExt}; + + // При варианте SWT.SAVE автоматически дописывается расширение, в отличие от OPEN + FileDialog dialog = new FileDialog(cellEditorWindow.getShell(), SWT.SAVE); + // поэтому вопрос о перезаписи регулируем через setOverwrite + dialog.setOverwrite(task.isSaveCommand()); + + if (currentFilepath.isBlank()) { + dialog.setFileName(currentFilenameExt); + } else { + File file = new File(currentFilepath); + dialog.setFileName(file.getName()); + dialog.setFilterPath(file.getPath()); + } + dialog.setText(Strings.TITLE_FILEDIALOG); + dialog.setFilterNames(filterNames); + dialog.setFilterExtensions(filterExt); + + return dialog.open(); + } + }; + + this.viewer = viewer; + } + + @Override + protected boolean canEdit(Object element) { + String paramKey = ((String[]) element)[0]; + if (isPasswordParam(paramKey)) { + return !currentUsernameValue.isBlank(); + } + return true; + } + + @Override + protected CellEditor getCellEditor(Object element) { + String[] e = (String[]) element; + + if (isUsernameParam(e[0])) { + return usernameEditor; + } else if (isFilepathParam(e)) { + return filenameEditor; + } else { + return textEditor; + } + } + + @Override + protected Object getValue(Object element) { + String[] e = (String[]) element; + + if (isUsernameParam(e[0])) { + return usernames.indexOf(e[1]); + } else { + return e[1]; + } + } + + @Override + protected void setValue(Object element, Object value) { + String paramKey = ((String[]) element)[0]; + String newParamValue = ""; + Integer valueIndex = null; + + // текстовое поле + if (value instanceof String) { + newParamValue = (String) value; + } + + // поле с выпадающим списком + if (value instanceof Integer) { + valueIndex = (Integer) value; + + if (isUsernameParam(paramKey) && valueIndex >= 0) { + // выбор логина из списка + newParamValue = usernames.get(valueIndex); + currentUsernameValue = newParamValue; + // установка пароля + params.put(PASSWORD_TITLE, infobasesCredentials.getOrDefault(newParamValue, "")); + + } else if (isUsernameParam(paramKey) && valueIndex == -1) { + // ввод нового логина вручную + newParamValue = ((CCombo) usernameEditor.getControl()).getText(); + currentUsernameValue = newParamValue; + if (!newParamValue.isBlank()) { + usernames.add(newParamValue); + usernameEditor.setItems(usernames.toArray(new String[0])); + } + } + } + + params.put(paramKey, newParamValue); + viewer.refresh(true); + } + } + + class ParamsContentProvider implements IStructuredContentProvider { + + /** + * Returns the elements in the input, which must be either an array or a Collection + * . + */ + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof Map) { + + List collection = new ArrayList<>(); + ((Map) inputElement) + .forEach( + (k, v) -> { + if (isPasswordParam(k)) { + // После редактирования пароль прячем за звездочками + collection.add(new String[] {k, v.isBlank() ? "" : "***"}); + } else { + collection.add(new String[] {k, v}); + } + }); + + return collection.toArray(); + } + return new Object[0]; + } + } + + private static class Strings { + + static final String TITLE_WINDOW = getString("Title"); + static final String TITLE_PARAMNAME = getString("ParamName"); + static final String TITLE_PARAMVALUE = getString("ParamValue"); + + static final String TITLE_FILEDIALOG = getString("TitleFileDialog"); + static final String FILTER_NAME = getString("FilterName"); + + static String getString(String key) { + return Messages.getString("BackgroundTaskParams." + key); + } + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/InfobaseDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/InfobaseDialog.java index 676193f..7d45902 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/InfobaseDialog.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/InfobaseDialog.java @@ -5,24 +5,32 @@ import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; +import java.util.GregorianCalendar; import java.util.List; import java.util.UUID; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.DateTime; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; +import ru.yanygin.clusterAdminLibrary.Config; import ru.yanygin.clusterAdminLibrary.Helper; import ru.yanygin.clusterAdminLibrary.Server; @@ -35,13 +43,20 @@ public class InfobaseDialog extends Dialog { private static final String DBMS_TYPE_ORACLEDATABASE = "OracleDatabase"; //$NON-NLS-1$ private static final String EMPTY_STRING = ""; //$NON-NLS-1$ - private final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //$NON-NLS-1$ + private final DateFormat dateReverseFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private final DateFormat dateDeniedFormat = new SimpleDateFormat("H:mm"); private final Date emptyDate = new Date(0); + private Font fontNormal; + private Font fontMicro; private Server server; private UUID clusterId; private UUID infoBaseId; private boolean creationMode = false; + private boolean deniedFriendlyEditMode = false; + + private final Image tumblerOn = Helper.getImage("tumblerOn.png"); + private final Image tumblerOff = Helper.getImage("tumblerOff.png"); // Controls private Text txtInfobaseName; @@ -55,9 +70,6 @@ public class InfobaseDialog extends Dialog { private Text txtExternalSessionManagerConnectionString; private Text txtSecurityProfile; private Text txtSafeModeSecurityProfile; - private Text txtDeniedMessage; - private Text deniedFromDate; - private Text deniedToDate; private Combo comboSecurityLevel; private Combo comboServerDbType; @@ -67,6 +79,12 @@ public class InfobaseDialog extends Dialog { private Button btnAllowDistributeLicense; private Button btnExternalSessionManagerRequired; + private Text txtDeniedMessage; + private Button btnDeniedSwitchMode; + + private DateTimeCombo deniedFromCombined; + private DateTimeCombo deniedToCombined; + /** * Create the dialog. * @@ -77,12 +95,14 @@ public class InfobaseDialog extends Dialog { */ public InfobaseDialog(Shell parentShell, Server server, UUID clusterId, UUID infoBaseId) { super(parentShell); - setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL); + setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL); this.server = server; this.clusterId = clusterId; this.infoBaseId = infoBaseId; - + + dateReverseFormat.setLenient(false); + // три варианта открытия окна: // - существующая база // - новая база @@ -192,26 +212,98 @@ protected Control createDialogArea(Composite parent) { lblDeniedFrom.setText(Strings.SESSIONS_DENIED_FROM); Composite compositeDeniedFrom = new Composite(container, SWT.NONE); - compositeDeniedFrom.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); - compositeDeniedFrom.setLayout(new FillLayout(SWT.HORIZONTAL)); + compositeDeniedFrom.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); + compositeDeniedFrom.setLayout(null); + + Text txtDeniedFromDate = new Text(compositeDeniedFrom, SWT.BORDER); + txtDeniedFromDate.setBounds(0, 1, 185, 21); + + DateTime deniedFromDate = new DateTime(compositeDeniedFrom, SWT.BORDER | SWT.DROP_DOWN); + deniedFromDate.setBounds(0, 0, 91, 23); + + DateTime deniedFromTime = new DateTime(compositeDeniedFrom, SWT.BORDER | SWT.TIME); + deniedFromTime.setBounds(96, 0, 70, 23); + + Combo comboDeniedFrom = new Combo(compositeDeniedFrom, SWT.READ_ONLY); + comboDeniedFrom.setBounds(96, 0, 90, 21); + + Button btnDeniedFromClear = new Button(compositeDeniedFrom, SWT.NONE); + btnDeniedFromClear.setText("X"); + btnDeniedFromClear.setBounds(184, -1, 23, 25); + btnDeniedFromClear.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + deniedFromCombined.clear(); + } + }); - deniedFromDate = new Text(compositeDeniedFrom, SWT.BORDER | SWT.DATE | SWT.DROP_DOWN); + btnDeniedSwitchMode = new Button(compositeDeniedFrom, SWT.CENTER); + btnDeniedSwitchMode.setToolTipText(Strings.SWITCH_DENIED_EDITING_MODE); + btnDeniedSwitchMode.setBounds(215, 1, 28, 21); + btnDeniedSwitchMode.setImage(tumblerOn); + btnDeniedSwitchMode.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + switchDeniedEditMode(); + } + }); Label lblDeniedTo = new Label(container, SWT.NONE); lblDeniedTo.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); lblDeniedTo.setText(Strings.SESSIONS_DENIED_TO); Composite compositeDeniedTo = new Composite(container, SWT.NONE); + compositeDeniedTo.setLayout(null); compositeDeniedTo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1)); - compositeDeniedTo.setLayout(new FillLayout(SWT.HORIZONTAL)); - deniedToDate = new Text(compositeDeniedTo, SWT.BORDER); + Text txtDeniedToDate = new Text(compositeDeniedTo, SWT.BORDER); + txtDeniedToDate.setBounds(0, 1, 185, 21); + + DateTime deniedToDate = new DateTime(compositeDeniedTo, SWT.BORDER | SWT.DROP_DOWN); + deniedToDate.setBounds(0, 0, 91, 23); + + DateTime deniedToTime = new DateTime(compositeDeniedTo, SWT.BORDER | SWT.TIME); + deniedToTime.setBounds(96, 0, 70, 23); + + Combo comboDeniedTo = new Combo(compositeDeniedTo, SWT.READ_ONLY); + comboDeniedTo.setBounds(96, 0, 90, 23); + + Button btnDeniedToClear = new Button(compositeDeniedTo, SWT.NONE); + btnDeniedToClear.setText("X"); + btnDeniedToClear.setBounds(184, -1, 23, 25); + btnDeniedToClear.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + deniedToCombined.clear(); + } + }); Label lblDeniedMessage = new Label(container, SWT.NONE); lblDeniedMessage.setText(Strings.SESSIONS_DENIED_MESSAGE); - txtDeniedMessage = new Text(container, SWT.BORDER | SWT.MULTI); + Button btnPutDeniedMessage = new Button(container, SWT.READ_ONLY); + btnPutDeniedMessage.setText(Strings.PUT_SESSIONS_DENIED_MESSAGE); + btnPutDeniedMessage.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + + String deniedMessage = + String.format( + Config.currentConfig.getInfobaseDeniedMessagePattern(), + deniedFromCombined.getDeniedTime(), + deniedToCombined.getDeniedTime()); + + txtDeniedMessage.setText(deniedMessage); + } + }); + + txtDeniedMessage = new Text(container, SWT.BORDER | SWT.WRAP | SWT.MULTI); GridData gdtxtDeniedMessage = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1); + gdtxtDeniedMessage.widthHint = 200; gdtxtDeniedMessage.heightHint = 63; txtDeniedMessage.setLayoutData(gdtxtDeniedMessage); @@ -262,6 +354,17 @@ protected Control createDialogArea(Composite parent) { txtSafeModeSecurityProfile = new Text(container, SWT.BORDER); txtSafeModeSecurityProfile.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + FontData fontData = deniedFromDate.getFont().getFontData()[0]; + fontNormal = + new Font( + getParentShell().getDisplay(), fontData.getName(), fontData.getHeight(), SWT.NORMAL); + fontMicro = new Font(getParentShell().getDisplay(), fontData.getName(), 1, SWT.NORMAL); + + deniedFromCombined = + new DateTimeCombo(txtDeniedFromDate, deniedFromDate, deniedFromTime, comboDeniedFrom); + deniedToCombined = + new DateTimeCombo(txtDeniedToDate, deniedToDate, deniedToTime, comboDeniedTo); + initProperties(); return container; @@ -292,8 +395,13 @@ private void initProperties() { // Lock properties btnSessionsDenied.setSelection(infoBaseInfo.isSessionsDenied()); - deniedFromDate.setText(convertDateToString(infoBaseInfo.getDeniedFrom())); - deniedToDate.setText(convertDateToString(infoBaseInfo.getDeniedTo())); + + deniedFriendlyEditMode = Config.currentConfig.getInfobaseDeniedFriendlyEditMode(); + setActiveDeniedFields(); + + // Даты запрета входа + deniedFromCombined.setDate(infoBaseInfo.getDeniedFrom(), true); + deniedToCombined.setDate(infoBaseInfo.getDeniedTo(), true); txtDeniedMessage.setText(infoBaseInfo.getDeniedMessage()); txtPermissionCode.setText(infoBaseInfo.getPermissionCode()); @@ -321,7 +429,6 @@ private boolean checkVariablesFromControls() { checksTextControls.add(txtInfobaseName); checksTextControls.add(txtServerDbName); checksTextControls.add(txtDatabaseDbName); - checksTextControls.add(txtDatabaseDbUser); for (Text control : checksTextControls) { if (control.getText().isBlank()) { @@ -332,18 +439,13 @@ private boolean checkVariablesFromControls() { } } - List checksDateControls = new ArrayList<>(); - checksDateControls.add(deniedFromDate); - checksDateControls.add(deniedToDate); + List checksDateControls = new ArrayList<>(); + checksDateControls.add(deniedFromCombined); + checksDateControls.add(deniedToCombined); - for (Text control : checksDateControls) { - if (control.getText().isBlank()) { - control.setBackground(Helper.getWhiteColor()); - } else { - if (convertStringToDate(control.getText()).equals(emptyDate)) { - control.setBackground(Helper.getPinkColor()); - existsError = true; - } + for (DateTimeCombo control : checksDateControls) { + if (!control.valueIsValid()) { + existsError = true; } } @@ -353,6 +455,7 @@ private boolean checkVariablesFromControls() { private boolean saveInfobaseProperties() { if (checkVariablesFromControls()) { + Helper.showMessageBox(Strings.SAVE_ERROR); return false; } @@ -376,8 +479,8 @@ private boolean saveInfobaseProperties() { // Lock properties infoBaseInfo.setSessionsDenied(btnSessionsDenied.getSelection()); - infoBaseInfo.setDeniedFrom(convertStringToDate(deniedFromDate.getText())); - infoBaseInfo.setDeniedTo(convertStringToDate(deniedToDate.getText())); + infoBaseInfo.setDeniedFrom(deniedFromCombined.getDate()); + infoBaseInfo.setDeniedTo(deniedToCombined.getDate()); infoBaseInfo.setDeniedMessage(txtDeniedMessage.getText()); infoBaseInfo.setPermissionCode(txtPermissionCode.getText()); @@ -403,20 +506,28 @@ private Date convertStringToDate(String date) { } Date convertDate; - + try { - convertDate = dateFormat.parse(date); + convertDate = dateReverseFormat.parse(date); } catch (ParseException excp) { - excp.printStackTrace(); - convertDate = emptyDate; + convertDate = null; } return convertDate; } - private String convertDateToString(Date date) { + private void switchDeniedEditMode() { + deniedFriendlyEditMode = !deniedFriendlyEditMode; + Config.currentConfig.setInfobaseDeniedFriendlyEditMode(deniedFriendlyEditMode); + + setActiveDeniedFields(); + } + + private void setActiveDeniedFields() { + deniedFromCombined.setEditMode(); + deniedToCombined.setEditMode(); - return date.equals(emptyDate) ? EMPTY_STRING : dateFormat.format(date); + btnDeniedSwitchMode.setImage(deniedFriendlyEditMode ? tumblerOn : tumblerOff); } /** @@ -450,6 +561,190 @@ public void widgetSelected(SelectionEvent e) { }); } + private class DateTimeCombo { + Text textField; + DateTime dateField; + DateTime timeField; + Combo comboField; + + boolean dateIsEmpty = false; + boolean deniedModifyEventOff = false; + + public DateTimeCombo(Text textField, DateTime dateField, DateTime timeField, Combo comboField) { + this.textField = textField; + this.dateField = dateField; + this.timeField = timeField; + this.comboField = comboField; + + for (int i = 0; i < 24; i++) { + this.comboField.add(String.format("%02d:00:00", i)); + this.comboField.add(" 15:00"); + this.comboField.add(" 30:00"); + this.comboField.add(" 45:00"); + } + + // установка обработчиков + this.textField.addModifyListener( + new ModifyListener() { + public void modifyText(ModifyEvent e) { + if (deniedModifyEventOff) { + deniedModifyEventOff = false; + return; + } + parseTextDate(); + } + }); + this.dateField.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + update(); + } + }); + this.timeField.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + update(); + } + }); + this.comboField.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateTime(); + } + }); + } + + private void parseTextDate() { + Date date = convertStringToDate(textField.getText()); + if (date != null) { + setDate(date, false); + } + } + + private void setDate(Date dateValue, boolean modifyTextField) { + dateIsEmpty = dateValue.equals(emptyDate); + updateEmptyState(); + + if (dateIsEmpty) { + timeField.setTime(timeField.getHours(), 0, 0); + comboField.select(timeField.getHours() * 4); + } else { + if (modifyTextField) { + deniedModifyEventOff = true; + textField.setText(convertDateToReverseString(dateValue)); + } + + dateField.setDate(dateValue.getYear() + 1900, dateValue.getMonth(), dateValue.getDate()); + timeField.setTime(dateValue.getHours(), dateValue.getMinutes(), dateValue.getSeconds()); + comboField.select(timeField.getHours() * 4); + } + } + + private void update() { + comboField.select(timeField.getHours() * 4); + + dateIsEmpty = false; + updateEmptyState(); + + Date deniedDate = getDate(); + deniedModifyEventOff = true; + textField.setText(convertDateToReverseString(deniedDate)); + } + + private void updateTime() { + int newMinutesIndex = comboField.getSelectionIndex(); + int newHourIndex = newMinutesIndex - (newMinutesIndex % 4); + String newHour = comboField.getItem(newHourIndex).substring(0, 2); + + timeField.setHours(Integer.parseInt(newHour)); + timeField.setMinutes(15 * (newMinutesIndex % 4)); + timeField.setSeconds(0); + + update(); + } + + private void updateEmptyState() { + if (dateIsEmpty) { + dateField.setFont(fontMicro); + timeField.setFont(fontMicro); + } else { + dateField.setFont(fontNormal); + timeField.setFont(fontNormal); + } + } + + private void clear() { + dateIsEmpty = true; + updateEmptyState(); + deniedModifyEventOff = true; + textField.setText(""); + + Date curDate = Calendar.getInstance().getTime(); + + dateField.setDate(curDate.getYear() + 1900, curDate.getMonth(), curDate.getDate()); + timeField.setTime(curDate.getHours(), 0, 0); + comboField.select(curDate.getHours() * 4); + } + + private Date getDate() { + if (dateIsEmpty) { + return emptyDate; + } + Calendar calendar = + new GregorianCalendar( + dateField.getYear(), + dateField.getMonth(), + dateField.getDay(), + timeField.getHours(), + timeField.getMinutes(), + timeField.getSeconds()); + return calendar.getTime(); + } + + private String getDeniedTime() { + if (dateIsEmpty) { + return "-"; + } + return dateDeniedFormat.format(getDate()); + } + + /** + * Преобразует дату к строке ("yyyy-MM-dd hh:MM:ss"). + * + * @param date - Дата + * @return Дата строкой + */ + private String convertDateToReverseString(Date date) { + + return date.equals(emptyDate) ? EMPTY_STRING : dateReverseFormat.format(date); + } + + private boolean valueIsValid() { + if (deniedFriendlyEditMode) { + return true; + } + if (textField.getText().isBlank()) { + textField.setBackground(Helper.getWhiteColor()); + } else if (convertStringToDate(textField.getText()) == null) { + textField.setBackground(Helper.getPinkColor()); + return false; + } else { + textField.setBackground(Helper.getWhiteColor()); + } + return true; + } + + private void setEditMode() { + textField.setVisible(!deniedFriendlyEditMode); + dateField.setVisible(deniedFriendlyEditMode); + timeField.setVisible(deniedFriendlyEditMode); + comboField.setVisible(deniedFriendlyEditMode); + } + } + private static class Strings { static final String TITLE_WINDOW = getString("TitleDialog"); @@ -470,6 +765,8 @@ private static class Strings { static final String SESSIONS_DENIED_FROM = getString("SessionsDeniedFrom"); static final String SESSIONS_DENIED_TO = getString("SessionsDeniedTo"); static final String SESSIONS_DENIED_MESSAGE = getString("SessionsDeniedMessage"); + static final String PUT_SESSIONS_DENIED_MESSAGE = getString("PutSessionsDeniedMessage"); + static final String SWITCH_DENIED_EDITING_MODE = getString("SwitchDeniedEditingMode"); static final String SESSIONS_PERMISSION_CODE = getString("SessionsPermissionCode"); static final String SESSIONS_DENIED_PARAMETER = getString("SessionsDeniedParameter"); static final String SHEDULED_JOBS_DENIED = getString("SheduledJobsDenied"); @@ -478,6 +775,7 @@ private static class Strings { getString("RequiredUseOfExternalManagement"); static final String SECURITY_PROFILE = getString("SecurityProfile"); static final String SAFE_MODE_SECURITY_PROFILE = getString("SafeModeSecurityProfile"); + static final String SAVE_ERROR = getString("SaveError"); static final String APPLY = Messages.getString("Dialogs.Apply"); diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/NewServersChoiseDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/NewServersChoiseDialog.java new file mode 100644 index 0000000..a5e8041 --- /dev/null +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/NewServersChoiseDialog.java @@ -0,0 +1,135 @@ +package ru.yanygin.clusterAdminLibraryUI; + +import java.util.List; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import ru.yanygin.clusterAdminLibrary.Helper; +import ru.yanygin.clusterAdminLibrary.Server; + +/** Форма для выбора, какие найденные сервера добавлять в список. */ +public class NewServersChoiseDialog extends Dialog { + private Table table; + private List newServers; + + /** + * Create the dialog. + * + * @param parentShell - parent shell + */ + public NewServersChoiseDialog(Shell parentShell) { + super(parentShell); + setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL); + } + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(Strings.TITLE_WINDOW); + } + + /** + * Create contents of the dialog. + * + * @param parent - parent composite + */ + @Override + protected Control createDialogArea(Composite parent) { + + Composite container = (Composite) super.createDialogArea(parent); + GridLayout gridLayout = (GridLayout) container.getLayout(); + gridLayout.marginHeight = 0; + gridLayout.marginWidth = 0; + + table = new Table(container, SWT.BORDER | SWT.CHECK | SWT.FULL_SELECTION); + table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumn columnHost = new TableColumn(table, SWT.LEFT); + columnHost.setResizable(false); + columnHost.setWidth(200); + columnHost.setText(Strings.HOST); + + TableColumn columnAgentPort = new TableColumn(table, SWT.LEFT); + columnAgentPort.setResizable(false); + columnAgentPort.setWidth(100); + columnAgentPort.setText(Strings.PORT); + + newServers = Helper.findNewServers(); + + table.removeAll(); + newServers.forEach( + (serv) -> { + TableItem item = new TableItem(table, SWT.NONE); + item.setText(0, serv.getAgentHost()); + item.setText(1, serv.getAgentPortAsString()); + item.setData(serv); + }); + + columnHost.pack(); + columnAgentPort.pack(); + + return container; + } + + private void saveNewServers() { + TableItem[] items = table.getItems(); + + for (TableItem tableItem : items) { + if (!tableItem.getChecked()) { + newServers.remove(tableItem.getData()); + } + } + } + + /** + * Получение списка серверов, выбранных пользователем. + * + * @return список новых серверов + */ + public List getNewServers() { + return newServers; + } + + /** + * Create contents of the button bar. + * + * @param parent - parent composite + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + Button button = + createButton(parent, IDialogConstants.FINISH_ID, IDialogConstants.OK_LABEL, true); + button.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + saveNewServers(); + close(); + } + }); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + private static class Strings { + static final String TITLE_WINDOW = Messages.getString("NewServersDialog.TitleDialog"); + static final String HOST = getString("Host"); + static final String PORT = getString("Port"); + + static String getString(String key) { + return Messages.getString("ServerDialog." + key); // $NON-NLS-1$ + } + } +} diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ServerDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ServerDialog.java index 3de6a0e..7d96602 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ServerDialog.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ServerDialog.java @@ -63,11 +63,11 @@ public class ServerDialog extends Dialog { private Text txtAgentHost; private Text txtAgentPort; private Text txtLocalRasPort; - + private Combo comboV8Version; private Link txtAgentCredential; - + private Table tableClusterCredentials; private Table tableInfobasesCredentials; @@ -121,127 +121,109 @@ protected Control createDialogArea(Composite parent) { GridLayout glConnectContainer = new GridLayout(2, false); connectContainer.setLayout(glConnectContainer); - Composite composite = new Composite(connectContainer, SWT.NONE); - composite.setLayout(new GridLayout(2, false)); - composite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); - - Label lblDescription = new Label(composite, SWT.NONE); - lblDescription.setText(Strings.SERVER_DESCRIPTION); - - txtDescription = new Text(composite, SWT.BORDER); - txtDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); - btnAutoconnect = new Button(connectContainer, SWT.CHECK); - GridData gdbtnAutoconnect = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + GridData gdbtnAutoconnect = new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1); gdbtnAutoconnect.horizontalIndent = 5; btnAutoconnect.setLayoutData(gdbtnAutoconnect); btnAutoconnect.setText(Strings.AUTOCONNECT_AT_STARTUP); - new Label(connectContainer, SWT.NONE); - radioUseRemoteRas = new Button(connectContainer, SWT.RADIO); - GridData gdradioUseRemoteRas = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); - gdradioUseRemoteRas.horizontalIndent = 5; - radioUseRemoteRas.setLayoutData(gdradioUseRemoteRas); - radioUseRemoteRas.setSelection(true); - radioUseRemoteRas.addSelectionListener( - new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - setEnabledRasGroupParameters(); - } - }); - radioUseRemoteRas.setBounds(0, 0, 90, 16); - radioUseRemoteRas.setText(Strings.USE_REMOTE_RAS); + Group grpDescription = new Group(connectContainer, SWT.NONE); + grpDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); + grpDescription.setText(Strings.SERVER_DESCRIPTION); + grpDescription.setLayout(new GridLayout(1, false)); - radioUseLocalRas = new Button(connectContainer, SWT.RADIO); - GridData gdradioUseLocalRas = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); - gdradioUseLocalRas.horizontalIndent = 5; - radioUseLocalRas.setLayoutData(gdradioUseLocalRas); - radioUseLocalRas.setBounds(0, 0, 90, 16); - radioUseLocalRas.setText(Strings.USE_LOCAL_RAS); + txtDescription = new Text(grpDescription, SWT.BORDER); + txtDescription.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + txtDescription.setSize(392, 21); - Group grpRemoteRasParameters = new Group(connectContainer, SWT.NONE); - grpRemoteRasParameters.setText(Strings.REMOTE_RAS_PARAMETERS); - grpRemoteRasParameters.setLayout(new GridLayout(2, false)); + Group grpRagentAddress = new Group(connectContainer, SWT.NONE); + grpRagentAddress.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); + grpRagentAddress.setText(Strings.AGENT_PARAMETERS); + grpRagentAddress.setLayout(new GridLayout(3, false)); - Label lblRasHost = new Label(grpRemoteRasParameters, SWT.NONE); - lblRasHost.setText(Strings.HOST); + Label lblV8Version = new Label(grpRagentAddress, SWT.NONE); + lblV8Version.setText(Strings.V8_VERSION); - Label lblRasPort = new Label(grpRemoteRasParameters, SWT.NONE); - lblRasPort.setSize(46, 15); - lblRasPort.setText(Strings.PORT); + Label lblAgentHost = new Label(grpRagentAddress, SWT.NONE); + lblAgentHost.setText(Strings.HOST); - txtRasHost = new Text(grpRemoteRasParameters, SWT.BORDER); - txtRasHost.addModifyListener( + Label lblAgentPort = new Label(grpRagentAddress, SWT.NONE); + lblAgentPort.setText(Strings.PORT); + + comboV8Version = new Combo(grpRagentAddress, SWT.NONE); + comboV8Version.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); + + txtAgentHost = new Text(grpRagentAddress, SWT.BORDER); + txtAgentHost.addModifyListener( new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (rasOnSameHost) { - txtAgentHost.setText(((Text) e.widget).getText()); + txtRasHost.setText(((Text) e.widget).getText()); } checkRasOnSameHost(); } }); - GridData gdtxtRasHost = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); - gdtxtRasHost.widthHint = 200; - txtRasHost.setLayoutData(gdtxtRasHost); - - txtRasPort = new Text(grpRemoteRasParameters, SWT.BORDER); - GridData gdtxtRasPort = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); - gdtxtRasPort.widthHint = 50; - txtRasPort.setLayoutData(gdtxtRasPort); - - Group grpLocalRasParameters = new Group(connectContainer, SWT.NONE); - grpLocalRasParameters.setSize(417, 90); - grpLocalRasParameters.setText(Strings.LOCAL_RAS_PARAMETERS); - grpLocalRasParameters.setLayout(new GridLayout(2, false)); - - Label lblV8Version = new Label(grpLocalRasParameters, SWT.NONE); - lblV8Version.setSize(124, 15); - lblV8Version.setText(Strings.V8_VERSION); - - Label lblLocalRasPort = new Label(grpLocalRasParameters, SWT.NONE); - lblLocalRasPort.setSize(77, 15); - lblLocalRasPort.setText(Strings.PORT); + GridData gdtxtAgentHost = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + gdtxtAgentHost.widthHint = 200; + txtAgentHost.setLayoutData(gdtxtAgentHost); - comboV8Version = new Combo(grpLocalRasParameters, SWT.READ_ONLY); - GridData gdcomboV8Version = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); - gdcomboV8Version.widthHint = 140; - comboV8Version.setLayoutData(gdcomboV8Version); - comboV8Version.setSize(389, 21); + txtAgentPort = new Text(grpRagentAddress, SWT.BORDER); + GridData gdtxtAgentPort = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + gdtxtAgentPort.widthHint = 50; + txtAgentPort.setLayoutData(gdtxtAgentPort); - txtLocalRasPort = new Text(grpLocalRasParameters, SWT.BORDER); - GridData gdtxtLocalRasPort = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); - gdtxtLocalRasPort.widthHint = 50; - txtLocalRasPort.setLayoutData(gdtxtLocalRasPort); + Group grpConnectParameters = new Group(connectContainer, SWT.NONE); + grpConnectParameters.setLayout(new GridLayout(3, false)); + grpConnectParameters.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 2, 1)); + grpConnectParameters.setText(Strings.CONNECTION_VARIANT); + new Label(grpConnectParameters, SWT.NONE); - Group grpRagentParameters = new Group(connectContainer, SWT.NONE); - grpRagentParameters.setText(Strings.AGENT_PARAMETERS); - grpRagentParameters.setLayout(new GridLayout(2, false)); + Label lblRasHost = new Label(grpConnectParameters, SWT.NONE); + lblRasHost.setText(Strings.HOST); - Label lblAgentHost = new Label(grpRagentParameters, SWT.NONE); - lblAgentHost.setText(Strings.HOST); + Label lblRasPort = new Label(grpConnectParameters, SWT.NONE); + lblRasPort.setSize(46, 15); + lblRasPort.setText(Strings.PORT); - Label lblAgentPort = new Label(grpRagentParameters, SWT.NONE); - lblAgentPort.setText(Strings.PORT); + radioUseRemoteRas = new Button(grpConnectParameters, SWT.RADIO); + radioUseRemoteRas.setSelection(true); + radioUseRemoteRas.addSelectionListener( + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setEnabledRasGroupParameters(); + } + }); + radioUseRemoteRas.setBounds(0, 0, 90, 16); + radioUseRemoteRas.setText(Strings.USE_REMOTE_RAS); - txtAgentHost = new Text(grpRagentParameters, SWT.BORDER); - txtAgentHost.addModifyListener( + txtRasHost = new Text(grpConnectParameters, SWT.BORDER); + GridData gdTxtRasHost = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + gdTxtRasHost.widthHint = 200; + txtRasHost.setLayoutData(gdTxtRasHost); + txtRasHost.addModifyListener( new ModifyListener() { @Override public void modifyText(ModifyEvent e) { checkRasOnSameHost(); } }); - GridData gdtxtAgentHost = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); - gdtxtAgentHost.widthHint = 200; - txtAgentHost.setLayoutData(gdtxtAgentHost); - txtAgentPort = new Text(grpRagentParameters, SWT.BORDER); - GridData gdtxtAgentPort = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1); - gdtxtAgentPort.widthHint = 50; - txtAgentPort.setLayoutData(gdtxtAgentPort); - new Label(connectContainer, SWT.NONE); + txtRasPort = new Text(grpConnectParameters, SWT.BORDER); + GridData gdTxtRasPort = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + gdTxtRasPort.widthHint = 50; + txtRasPort.setLayoutData(gdTxtRasPort); + + radioUseLocalRas = new Button(grpConnectParameters, SWT.RADIO); + radioUseLocalRas.setBounds(0, 0, 90, 16); + radioUseLocalRas.setText(Strings.USE_LOCAL_RAS); + new Label(grpConnectParameters, SWT.NONE); + + txtLocalRasPort = new Text(grpConnectParameters, SWT.BORDER); + GridData gdTxtLocalRasPort = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + gdTxtLocalRasPort.widthHint = 50; + txtLocalRasPort.setLayoutData(gdTxtLocalRasPort); TabItem tabCredentials = new TabItem(tabFolder, SWT.NONE); tabCredentials.setText(Strings.CREDENTIALS); @@ -357,22 +339,20 @@ private void initProperties() { if (server != null) { txtDescription.setText(server.getDescription()); - txtRasHost.setText(server.getRasHost()); - txtRasPort.setText(server.getRasPortAsString()); - + comboV8Version.setItems(getInstalledV8Versions()); + comboV8Version.setText(server.getV8Version()); txtAgentHost.setText(server.getAgentHost()); txtAgentPort.setText(server.getAgentPortAsString()); + btnAutoconnect.setSelection(server.getAutoconnect()); + radioUseRemoteRas.setSelection(!server.getUseLocalRas()); radioUseLocalRas.setSelection(server.getUseLocalRas()); - comboV8Version.setItems(getInstalledV8Versions()); - comboV8Version.setText(server.getLocalRasV8version()); - + txtRasHost.setText(server.getRasHost()); + txtRasPort.setText(server.getRasPortAsString()); txtLocalRasPort.setText(server.getLocalRasPortAsString()); - btnAutoconnect.setSelection(server.getAutoconnect()); - saveCredentialsVariant = server.getSaveCredentialsVariant(); btnSaveCredentialsDisable.setSelection( saveCredentialsVariant.equals(SaveCredentialsVariant.DISABLE)); @@ -430,7 +410,7 @@ private String morphToLink(String text) { private String[] getInstalledV8Versions() { List installedV8Versions = new ArrayList<>(); - Helper.getInstalledV8Versions().forEach((desc, path) -> installedV8Versions.add(desc)); + Helper.getInstalledV8Versions("x64").forEach((desc, path) -> installedV8Versions.add(desc)); installedV8Versions.sort(String.CASE_INSENSITIVE_ORDER); return installedV8Versions.toArray(new String[0]); } @@ -455,7 +435,6 @@ private void checkRasOnSameHost() { private void setEnabledRasGroupParameters() { txtRasHost.setEnabled(radioUseRemoteRas.getSelection()); txtRasPort.setEnabled(radioUseRemoteRas.getSelection()); - comboV8Version.setEnabled(!radioUseRemoteRas.getSelection()); txtLocalRasPort.setEnabled(!radioUseRemoteRas.getSelection()); } @@ -463,16 +442,17 @@ private boolean saveNewServerProperties() { try { server.setDescription(txtDescription.getText()); + server.setV8Version(comboV8Version.getText()); server.setAgentHost(txtAgentHost.getText()); server.setAgentPort(Integer.parseInt(txtAgentPort.getText())); + + server.setAutoconnect(btnAutoconnect.getSelection()); + + server.setUseLocalRas(!radioUseRemoteRas.getSelection()); server.setRasHost(txtRasHost.getText()); server.setRasPort(Integer.parseInt(txtRasPort.getText())); - server.setUseLocalRas(!radioUseRemoteRas.getSelection()); server.setLocalRasPort(Integer.parseInt(txtLocalRasPort.getText())); - server.setLocalRasV8version(comboV8Version.getText()); - server.setAutoconnect(btnAutoconnect.getSelection()); - extractSaveCredentialsVariant(); server.setSaveCredentialsVariant(saveCredentialsVariant); @@ -618,14 +598,13 @@ private static class Strings { static final String TITLE_WINDOW = getString("TitleDialog"); static final String CONNECT_PARAMETERS = getString("ConnectParameters"); + static final String CONNECTION_VARIANT = getString("ConnectionVariant"); static final String SERVER_DESCRIPTION = getString("Description"); static final String AUTOCONNECT_AT_STARTUP = getString("AutoconnectAtStartup"); static final String USE_REMOTE_RAS = getString("UseRemoteRAS"); static final String USE_LOCAL_RAS = getString("UseLocalRAS"); - static final String REMOTE_RAS_PARAMETERS = getString("RemoteRASParameters"); static final String HOST = getString("Host"); static final String PORT = getString("Port"); - static final String LOCAL_RAS_PARAMETERS = getString("LocalRASParameters"); static final String V8_VERSION = getString("V8Version"); static final String AGENT_PARAMETERS = getString("AgentParameters"); static final String CREDENTIALS = getString("Credentials"); diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/SettingsDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/SettingsDialog.java index 1cfa7ed..5a9fb79 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/SettingsDialog.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/SettingsDialog.java @@ -7,6 +7,7 @@ import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -44,11 +45,23 @@ public class SettingsDialog extends Dialog { private Button btnShadowSleepSessions; private Button btnReadClipboard; private Button btnCheckUpdate; + private Button btnShowCurrentDateAsTime; private Button btnRowSortAsPrevious; private Button btnRowSortAsc; private Button btnRowSortDesc; + private Button btnLoggerLevelOff; + private Button btnLoggerLevelError; + private Button btnLoggerLevelWarning; + private Button btnLoggerLevelInfo; + private Button btnLoggerLevelDebug; + private Button btnRequestLogon; private static final String LOCALE_RU = "ru-RU"; //$NON-NLS-1$ + private Text txtIbasesFilePath; + private Label lblInfobaseDeniedEditMode; + private Text txtInfobaseDeniedPattern; + private Button btnInfobaseDeniedStandardEditMode; + private Button btnInfobaseDeniedFriendlyEditMode; /** * Создание диалога настроек сервера. @@ -130,7 +143,7 @@ protected Control createDialogArea(Composite parent) { Group grpLocale = new Group(container, SWT.NONE); grpLocale.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); - grpLocale.setText(Strings.LOCALE); + grpLocale.setText(Strings.LOCALE_TITLE); grpLocale.setLayout(new GridLayout(1, false)); btnLocaleSystem = new Button(grpLocale, SWT.RADIO); @@ -143,7 +156,8 @@ protected Control createDialogArea(Composite parent) { btnLocaleRussian.setText(Strings.LOCALE_RUSSIAN); Group grpHighlight = new Group(container, SWT.NONE); - grpHighlight.setText(Strings.HIGHLIGHT); + grpHighlight.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); + grpHighlight.setText(Strings.HIGHLIGHT_TITLE); grpHighlight.setLayout(new GridLayout(2, false)); btnHighlightNewItems = new Button(grpHighlight, SWT.CHECK); @@ -187,7 +201,8 @@ protected Control createDialogArea(Composite parent) { lblWatchSessionsColor.setLayoutData(gdLblWatchSessionsColor); Group grpRowSortDirection = new Group(container, SWT.NONE); - grpRowSortDirection.setText(Strings.ROW_SORT_DIRECTION); + grpRowSortDirection.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); + grpRowSortDirection.setText(Strings.ROW_SORT_DIRECTION_TITLE); grpRowSortDirection.setLayout(new GridLayout(1, false)); btnRowSortAsPrevious = new Button(grpRowSortDirection, SWT.RADIO); @@ -199,15 +214,72 @@ protected Control createDialogArea(Composite parent) { btnRowSortDesc = new Button(grpRowSortDirection, SWT.RADIO); btnRowSortDesc.setText(Strings.ROW_SORT_DIRECTION_DESCENDING); - btnReadClipboard = new Button(container, SWT.CHECK); - btnReadClipboard.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); + Group grpLoggerLevel = new Group(container, SWT.NONE); + grpLoggerLevel.setLayout(new GridLayout(1, false)); + grpLoggerLevel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); + grpLoggerLevel.setText(Strings.LOGGER_LEVEL_TITLE); + + btnLoggerLevelOff = new Button(grpLoggerLevel, SWT.RADIO); + btnLoggerLevelOff.setText("off"); + + btnLoggerLevelError = new Button(grpLoggerLevel, SWT.RADIO); + btnLoggerLevelError.setText("error"); + + btnLoggerLevelWarning = new Button(grpLoggerLevel, SWT.RADIO); + btnLoggerLevelWarning.setText("warning"); + + btnLoggerLevelInfo = new Button(grpLoggerLevel, SWT.RADIO); + btnLoggerLevelInfo.setText("info"); + + btnLoggerLevelDebug = new Button(grpLoggerLevel, SWT.RADIO); + btnLoggerLevelDebug.setText("debug"); + + Group grpOther = new Group(container, SWT.NONE); + grpOther.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); + grpOther.setLayout(new GridLayout(1, false)); + + btnReadClipboard = new Button(grpOther, SWT.CHECK); btnReadClipboard.setText(Strings.READ_CLIPBOARD); - btnCheckUpdate = new Button(container, SWT.CHECK); - btnCheckUpdate.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); + btnCheckUpdate = new Button(grpOther, SWT.CHECK); btnCheckUpdate.setText(Strings.CHECK_UPDATE); - new Label(container, SWT.NONE); + btnShowCurrentDateAsTime = new Button(grpOther, SWT.CHECK); + btnShowCurrentDateAsTime.setText(Strings.SHOW_CURRENT_DATE_AS_TIME); + + btnRequestLogon = new Button(grpOther, SWT.CHECK); + btnRequestLogon.setText(Strings.REQUEST_LOGON); + + Label lblIbasesFilePath = new Label(grpOther, SWT.NONE); + lblIbasesFilePath.setText(Strings.IBASES_PATH_TITLE); + + txtIbasesFilePath = new Text(grpOther, SWT.BORDER); + txtIbasesFilePath.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + + Group grpInfobaseDenied = new Group(container, SWT.NONE); + grpInfobaseDenied.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); + grpInfobaseDenied.setLayout(new GridLayout(1, false)); + + lblInfobaseDeniedEditMode = new Label(grpInfobaseDenied, SWT.CHECK); + lblInfobaseDeniedEditMode.setText(Strings.INFOBASE_DENIED_EDIT_MODE); + + Composite compositeInfobaseDeniedEditMode = new Composite(grpInfobaseDenied, SWT.NONE); + compositeInfobaseDeniedEditMode.setLayout(new FillLayout(SWT.HORIZONTAL)); + + btnInfobaseDeniedStandardEditMode = new Button(compositeInfobaseDeniedEditMode, SWT.RADIO); + btnInfobaseDeniedStandardEditMode.setText(Strings.INFOBASE_DENIED_STANDARD_EDIT_MODE); + + btnInfobaseDeniedFriendlyEditMode = new Button(compositeInfobaseDeniedEditMode, SWT.RADIO); + btnInfobaseDeniedFriendlyEditMode.setText(Strings.INFOBASE_DENIED_FRIENDLY_EDIT_MODE); + + Label lblInfobaseDeniedPattern = new Label(grpInfobaseDenied, SWT.NONE); + lblInfobaseDeniedPattern.setText(Strings.INFOBASE_DENIED_MESSAGE_PATTERN); + + txtInfobaseDeniedPattern = new Text(grpInfobaseDenied, SWT.BORDER | SWT.WRAP | SWT.MULTI); + GridData gdTxtInfobaseDeniedPattern = new GridData(SWT.FILL, SWT.FILL, false, true, 1, 1); + gdTxtInfobaseDeniedPattern.widthHint = 200; + gdTxtInfobaseDeniedPattern.heightHint = 61; + txtInfobaseDeniedPattern.setLayoutData(gdTxtInfobaseDeniedPattern); initProperties(); @@ -235,18 +307,34 @@ private void initProperties() { btnShadowSleepSessions.setSelection(config.isShadeSleepingSessions()); btnReadClipboard.setSelection(config.isReadClipboard()); btnCheckUpdate.setSelection(config.checkingUpdate()); - - if (config.getLocale() == null) { + btnShowCurrentDateAsTime.setSelection(config.showCurrentDateAsTime()); + + btnInfobaseDeniedStandardEditMode.setSelection(!config.getInfobaseDeniedFriendlyEditMode()); + btnInfobaseDeniedFriendlyEditMode.setSelection(config.getInfobaseDeniedFriendlyEditMode()); + txtInfobaseDeniedPattern.setText(config.getInfobaseDeniedMessagePattern()); + + final String locale = config.getLocale(); + if (locale == null) { btnLocaleSystem.setSelection(true); } else { - btnLocaleEnglish.setSelection(config.getLocale().equals(Locale.ENGLISH.toLanguageTag())); - btnLocaleRussian.setSelection(config.getLocale().equals(LOCALE_RU)); + btnLocaleEnglish.setSelection(locale.equals(Locale.ENGLISH.toLanguageTag())); + btnLocaleRussian.setSelection(locale.equals(LOCALE_RU)); } final RowSortDirection rowSortDirection = config.getRowSortDirection(); btnRowSortAsPrevious.setSelection(rowSortDirection == RowSortDirection.DISABLE); btnRowSortAsc.setSelection(rowSortDirection == RowSortDirection.ASC); btnRowSortDesc.setSelection(rowSortDirection == RowSortDirection.DESC); + + final String loggerLevel = config.getLoggerLevel(); + btnLoggerLevelOff.setSelection(loggerLevel.equals(btnLoggerLevelOff.getText())); + btnLoggerLevelError.setSelection(loggerLevel.equals(btnLoggerLevelError.getText())); + btnLoggerLevelWarning.setSelection(loggerLevel.equals(btnLoggerLevelWarning.getText())); + btnLoggerLevelInfo.setSelection(loggerLevel.equals(btnLoggerLevelInfo.getText())); + btnLoggerLevelDebug.setSelection(loggerLevel.equals(btnLoggerLevelDebug.getText())); + + txtIbasesFilePath.setText(config.getIbasesStringPath()); + btnRequestLogon.setSelection(config.getRequestLogon()); } private void saveProperties() { @@ -270,6 +358,9 @@ private void saveProperties() { config.setShadowSleepSessions(btnShadowSleepSessions.getSelection()); config.setReadClipboard(btnReadClipboard.getSelection()); config.setCheckingUpdate(btnCheckUpdate.getSelection()); + config.setShowCurrentDateAsTime(btnShowCurrentDateAsTime.getSelection()); + config.setInfobaseDeniedFriendlyEditMode(btnInfobaseDeniedFriendlyEditMode.getSelection()); + config.setInfobaseDeniedMessagePattern(txtInfobaseDeniedPattern.getText()); if (btnLocaleSystem.getSelection()) { config.setLocale(null); @@ -289,6 +380,24 @@ private void saveProperties() { config.setRowSortDirection(RowSortDirection.DISABLE); } + String loggerLevel; + if (btnLoggerLevelOff.getSelection()) { + loggerLevel = btnLoggerLevelOff.getText(); + } else if (btnLoggerLevelError.getSelection()) { + loggerLevel = btnLoggerLevelError.getText(); + } else if (btnLoggerLevelWarning.getSelection()) { + loggerLevel = btnLoggerLevelWarning.getText(); + } else if (btnLoggerLevelInfo.getSelection()) { + loggerLevel = btnLoggerLevelInfo.getText(); + } else if (btnLoggerLevelDebug.getSelection()) { + loggerLevel = btnLoggerLevelDebug.getText(); + } else { + loggerLevel = btnLoggerLevelOff.getText(); + } + config.setLoggerLevel(loggerLevel); + + config.setIbasesPath(txtIbasesFilePath.getText()); + config.setRequestLogon(btnRequestLogon.getSelection()); } /** @@ -333,24 +442,37 @@ private static class Strings { static final String SHOW_INFOBASE_DESCRIPTION = getString("ShowInfobaseDescription"); static final String SHOW_LOCAL_RAS_CONNECTINFO = getString("ShowLocalRASConnectInfo"); - static final String LOCALE = getString("Locale"); + static final String LOCALE_TITLE = getString("LocaleTitle"); static final String LOCALE_SYSTEM = getString("LocaleSystem"); static final String LOCALE_ENGLISH = getString("LocaleEnglish"); static final String LOCALE_RUSSIAN = getString("LocaleRussian"); - static final String HIGHLIGHT = getString("Highlight"); + static final String HIGHLIGHT_TITLE = getString("HighlightTitle"); static final String HIGHLIGHT_NEW_ITEMS = getString("HighlightNewItems"); static final String HIGHLIGHT_DURATION = getString("HighlightDuration"); static final String SHADOW_SLEEP_SESSIONS = getString("ShadowSleepSessions"); static final String WATCH_SESSIONS = getString("WatchSessions"); - static final String ROW_SORT_DIRECTION = getString("RowSortDirection"); + static final String ROW_SORT_DIRECTION_TITLE = getString("RowSortDirectionTitle"); static final String ROW_SORT_DIRECTION_AS_PREVIOUS = getString("RowSortDirectionAsPrevious"); static final String ROW_SORT_DIRECTION_ASCENDING = getString("RowSortDirectionAscending"); static final String ROW_SORT_DIRECTION_DESCENDING = getString("RowSortDirectionDescending"); static final String READ_CLIPBOARD = getString("ReadClipboard"); static final String CHECK_UPDATE = getString("CheckUpdate"); + static final String SHOW_CURRENT_DATE_AS_TIME = getString("ShowCurrentDateAsTime"); + + static final String INFOBASE_DENIED_EDIT_MODE = getString("InfobaseDeniedEditMode"); + static final String INFOBASE_DENIED_STANDARD_EDIT_MODE = + getString("InfobaseDeniedStandardEditMode"); + static final String INFOBASE_DENIED_FRIENDLY_EDIT_MODE = + getString("InfobaseDeniedFriendlyEditMode"); + static final String INFOBASE_DENIED_MESSAGE_PATTERN = getString("InfobaseDeniedMessagePattern"); + + static final String LOGGER_LEVEL_TITLE = getString("LoggerLevelTitle"); + + static final String REQUEST_LOGON = getString("RequestLogon"); + static final String IBASES_PATH_TITLE = getString("IbasesFilePathTitle"); static String getString(String key) { return Messages.getString("SettingsDialog." + key); //$NON-NLS-1$ diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ViewerArea.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ViewerArea.java index 1b192ee..4d479b9 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ViewerArea.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/ViewerArea.java @@ -1,22 +1,39 @@ package ru.yanygin.clusterAdminLibraryUI; +import com._1c.v8.ibis.admin.IAssignmentRuleInfo; import com._1c.v8.ibis.admin.IClusterInfo; import com._1c.v8.ibis.admin.IInfoBaseInfo; import com._1c.v8.ibis.admin.IWorkingProcessInfo; import com._1c.v8.ibis.admin.IWorkingServerInfo; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.Arrays; import java.util.EnumMap; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Timer; +import java.util.TimerTask; import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.FocusAdapter; +import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.KeyAdapter; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.MouseAdapter; @@ -30,18 +47,20 @@ import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; -import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.swt.widgets.Tree; @@ -50,6 +69,10 @@ import org.eclipse.swt.widgets.Widget; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ru.yanygin.clusterAdminLibrary.AssignmentRuleContentProvider; +import ru.yanygin.clusterAdminLibrary.AssignmentRuleLabelProvider; +import ru.yanygin.clusterAdminLibrary.BackgroundTask; +import ru.yanygin.clusterAdminLibrary.BackgroundTask.V8ActionVariant; import ru.yanygin.clusterAdminLibrary.BaseInfoExtended; import ru.yanygin.clusterAdminLibrary.ClusterProvider; import ru.yanygin.clusterAdminLibrary.ColumnProperties; @@ -80,10 +103,10 @@ public class ViewerArea extends Composite { // Image clusterAdd48Icon; // Image infobaseAdd48Icon; - Image serverIcon; - Image serverConnectedIcon; - Image serverDisconnectIcon; - Image serverConnectingIcon; + // Image serverIcon; + // Image serverConnectedIcon; + // Image serverDisconnectIcon; + // Image serverConnectingIcon; Image workingServerIcon; Image infobaseIcon; Image infobasesIcon; @@ -93,15 +116,26 @@ public class ViewerArea extends Composite { Image workingProcessIcon; Image connectActionIcon; Image disconnectActionIcon; - Image editIcon; - Image addIcon; - Image deleteIcon; Image lockUsersIcon; - Image updateIcon; + + Image addIcon16; + Image editIcon16; + Image deleteIcon16; + Image viewIcon16; + Image updateIcon16; + + Image addIcon24; + Image editIcon24; + Image deleteIcon24; + Image updateIcon24; + Image updateAutoIcon24; + Image favoritesIcon; Image sortIcon; Image moveUpIcon; Image moveDownIcon; + Image watchSession; + Image roubleIcon; Tree serversTree; TreeItem currentTreeItem; @@ -114,16 +148,21 @@ public class ViewerArea extends Composite { Menu infobaseNodeMenu; Menu infobaseMenu; - TabItem tabSessions; - TabItem tabConnections; - TabItem tabLocks; - TabItem tabWorkingProcesses; - TabItem tabWorkingServers; - TabItem currentTab; + Table tableSessions; + Table tableConnections; + Table tableLocks; + Table tableWorkingProcesses; + Table tableWorkingServers; + Table currentTable; + + Table tableTasks; + TabItem tabTask; + Text tableTaskLog; ToolItem addToolbarItem; ToolItem editToolbarItem; ToolItem deleteToolbarItem; + TableViewer tnfTableViewer; TreeColumn columnServer; @@ -155,10 +194,17 @@ public enum TreeItemType { Map toolbarCreateListeners = new EnumMap<>(TreeItemType.class); Map toolbarEditListeners = new EnumMap<>(TreeItemType.class); Map toolbarDeleteListeners = new EnumMap<>(TreeItemType.class); - Map tableContextItemEdit = new HashMap<>(); - Map tableContextItemDelete = new HashMap<>(); Map serversTreeContextMenus = new EnumMap<>(TreeItemType.class); - Map> linksTablesToExtendedClass = new HashMap<>(); + + // List userScripts = new ArrayList<>(); + Timer taskTimer; + Timer serverConnectionTimer; + Timer updateListTimer; + + List waitingConnectServers = new ArrayList<>(); + + RefreshTablesSelectionListener refreshTablesListener; + // UserScriptRunner userScriptRunner; // @Slf4j /** @@ -169,7 +215,7 @@ public enum TreeItemType { * @param menu - menu * @param toolBar - toolBar * @param clusterProvider - clusterProvider - * @param configPath - путь к файлу конфигурации + * @param config - путь к файлу конфигурации */ public ViewerArea( Composite parent, @@ -181,84 +227,138 @@ public ViewerArea( super(parent, style); this.clusterProvider = clusterProvider; - // this.clusterProvider.readConfig(); - // this.config = ClusterProvider.getCommonConfig(); this.config = config; + this.setLayout(new FillLayout(SWT.HORIZONTAL)); initIcon(); - BaseInfoExtended.init(); - - SashForm sashForm = new SashForm(this, SWT.NONE); + initMainMenu(menu); + initToolbar(toolBar); // toolBar = new ToolBar(this, SWT.FLAT | SWT.RIGHT); // Для отладки // toolBar.setBounds(0, 0, 500, 23); // Для отладки + + BaseInfoExtended.init(); + + TabFolder mainTabFolder = new TabFolder(this, SWT.BOTTOM); + initServersTab(mainTabFolder); + initTaskTab(mainTabFolder); - initToolbar(toolBar); - initMainMenu(menu); + runAutonnectAllServers(); + } + + private void initServersTab(TabFolder mainTabFolder) { + TabItem tabServers = new TabItem(mainTabFolder, SWT.NONE); + tabServers.setText(Strings.MENU_SERVERS); - initServersTree(sashForm); + // инициализация таблиц управления серверами + SashForm sashServers = new SashForm(mainTabFolder, SWT.NONE); + tabServers.setControl(sashServers); - TabFolder tabFolder = new TabFolder(sashForm, SWT.NONE); + initServersTree(sashServers); + TabFolder tabFolder = new TabFolder(sashServers, SWT.NONE); tabFolder.addSelectionListener( new SelectionAdapter() { - @Override public void widgetSelected(SelectionEvent evt) { - currentTab = tabFolder.getSelection()[0]; - fillTabs(); + TabItem currentTab = tabFolder.getSelection()[0]; + currentTable = getTable(currentTab); + refreshCurrentList(); } }); - tabSessions = initListTable(tabFolder, SessionInfoExtended.class, true); - tabConnections = initListTable(tabFolder, ConnectionInfoExtended.class, false); - tabLocks = initListTable(tabFolder, LockInfoExtended.class, false); - tabWorkingProcesses = initListTable(tabFolder, WorkingProcessInfoExtended.class, false); - tabWorkingServers = initListTable(tabFolder, WorkingServerInfoExtended.class, false); - //////////////////////////////////////////// + // Таблица сеансов + TabItem tabSessions = new TabItem(tabFolder, SWT.NONE); + tableSessions = initTable(tabFolder, SessionInfoExtended.class); + tabSessions.setControl(tableSessions); + BaseInfoExtended.linkTabItem(SessionInfoExtended.class, tabSessions); + tableSessions.setFocus(); + + // Таблица соединений + TabItem tabConnections = new TabItem(tabFolder, SWT.NONE); + tableConnections = initTable(tabFolder, ConnectionInfoExtended.class); + tabConnections.setControl(tableConnections); + BaseInfoExtended.linkTabItem(ConnectionInfoExtended.class, tabConnections); + + // Таблица блокировок + TabItem tabLocks = new TabItem(tabFolder, SWT.NONE); + tableLocks = initTable(tabFolder, LockInfoExtended.class); + tabLocks.setControl(tableLocks); + BaseInfoExtended.linkTabItem(LockInfoExtended.class, tabLocks); + + // Таблица рабочих процессов + TabItem tabWorkingProcesses = new TabItem(tabFolder, SWT.NONE); + tableWorkingProcesses = initTable(tabFolder, WorkingProcessInfoExtended.class); + tabWorkingProcesses.setControl(tableWorkingProcesses); + BaseInfoExtended.linkTabItem(WorkingProcessInfoExtended.class, tabWorkingProcesses); - initMaps(); + // Таблица рабочих серверов + TabItem tabWorkingServers = new TabItem(tabFolder, SWT.NONE); - initTableContextMenu(tabSessions, true, false, true, true); - initTableContextMenu(tabConnections, true, false, false, true); - initTableContextMenu(tabLocks, true, false, false, false); - initTableContextMenu(tabWorkingProcesses, true, false, false, false); - initTableContextMenu(tabWorkingServers, true, true, true, true); - ////////////////////////////////////////////// + SashForm sashWorkingServers = new SashForm(tabFolder, SWT.VERTICAL); - clearTabs(); + tableWorkingServers = initTable(sashWorkingServers, WorkingServerInfoExtended.class); + + initAssRuleTable(sashWorkingServers); + BaseInfoExtended.linkTabItem(WorkingServerInfoExtended.class, tabWorkingServers); + + tabWorkingServers.setControl(sashWorkingServers); + sashWorkingServers.setWeights(5, 10); // Пропорции областей + + initTableContextMenu(tnfTableViewer.getTable(), IAssignmentRuleInfo.class); + + initToolbarListeners(); + clearTabs(false); // TODO тут вроде не нужно BaseInfoExtended.resetTabsTextCount(); setEnableToolbarItems(); - this.setLayout(new FillLayout(SWT.HORIZONTAL)); - // Пропорции областей - sashForm.setWeights(3, 10); + sashServers.setWeights(3, 10); + } - // Заполнение списка серверов - config - .getServers() - .forEach( - (serverKey, server) -> { - addServerItemInServersTree(server); - }); + private void initTaskTab(TabFolder mainTabFolder) { + tabTask = new TabItem(mainTabFolder, SWT.NONE); + tabTask.setText("Task"); - runAutonnectAllServers(); + SashForm sashTasks = new SashForm(mainTabFolder, SWT.NONE); + tabTask.setControl(sashTasks); + + tableTasks = new Table(sashTasks, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); + tableTasks.setHeaderVisible(true); + tableTasks.setLinesVisible(true); + tableTasks.addMouseListener(tableTaskMouseClickListener); + + addTaskTableColumn(tableTasks, "Task", 200); + addTaskTableColumn(tableTasks, "State", 50); + addTaskTableColumn(tableTasks, "Start", 120, SWT.RIGHT); + addTaskTableColumn(tableTasks, "End", 120); + addTaskTableColumn(tableTasks, "Params", 120); + + tableTaskLog = new Text(sashTasks, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.READ_ONLY); + tableTaskLog.addListener( + SWT.Modify, + new Listener() { + public void handleEvent(Event e) { + tableTaskLog.setTopIndex(tableTaskLog.getLineCount() - 1); + } + }); + // Пропорции областей + sashTasks.setWeights(7, 10); } private void initIcon() { - LOGGER.info("Start init icon"); //$NON-NLS-1$ + LOGGER.debug("Start init icon"); //$NON-NLS-1$ // serverAdd48Icon = Helper.getImage("server_add_48.png"); //$NON-NLS-1$ // clusterAdd48Icon = Helper.getImage("cluster_add_48.png"); //$NON-NLS-1$ // infobaseAdd48Icon = Helper.getImage("infobase_add_48.png"); //$NON-NLS-1$ - serverIcon = Helper.getImage("server_24.png"); //$NON-NLS-1$ - serverConnectedIcon = Helper.getImage("server_connected_24.png"); //$NON-NLS-1$ - serverDisconnectIcon = Helper.getImage("server_disconnect_24.png"); //$NON-NLS-1$ - serverConnectingIcon = Helper.getImage("server_connecting_24.png"); //$NON-NLS-1$ - - workingServerIcon = Helper.getImage("working_server_24.png"); //$NON-NLS-1$ + // serverIcon = Helper.getImage("server_24.png"); //$NON-NLS-1$ + // serverConnectedIcon = Helper.getImage("server_connected_24.png"); //$NON-NLS-1$ + // serverDisconnectIcon = Helper.getImage("server_disconnect_24.png"); //$NON-NLS-1$ + // serverConnectingIcon = Helper.getImage("server_connecting_24.png"); //$NON-NLS-1$ + + workingServerIcon = Helper.getImage("working_server_24.png"); // $NON-NLS-1$ // infobaseIcon = Helper.getImage("infobase_24.png"); //$NON-NLS-1$ infobasesIcon = Helper.getImage("infobases_24.png"); //$NON-NLS-1$ clusterIcon = Helper.getImage("cluster_24.png"); //$NON-NLS-1$ @@ -268,18 +368,29 @@ private void initIcon() { connectActionIcon = Helper.getImage("connect_action_24.png"); //$NON-NLS-1$ disconnectActionIcon = Helper.getImage("disconnect_action_24.png"); //$NON-NLS-1$ + lockUsersIcon = Helper.getImage("lock_users_16.png"); // $NON-NLS-1$ + + editIcon16 = Helper.getImage("edit_16.png"); // $NON-NLS-1$ + addIcon16 = Helper.getImage("add_16.png"); // $NON-NLS-1$ + deleteIcon16 = Helper.getImage("delete_16.png"); // $NON-NLS-1$ + viewIcon16 = Helper.getImage("view_16.png"); // $NON-NLS-1$ + updateIcon16 = Helper.getImage("update_16.png"); // $NON-NLS-1$ + + editIcon24 = Helper.getImage("edit_24.png"); // $NON-NLS-1$ + addIcon24 = Helper.getImage("add_24.png"); // $NON-NLS-1$ + deleteIcon24 = Helper.getImage("delete_24.png"); // $NON-NLS-1$ + updateIcon24 = Helper.getImage("update_24.png"); // $NON-NLS-1$ + updateAutoIcon24 = Helper.getImage("updateAuto_24.png"); // $NON-NLS-1$ - editIcon = Helper.getImage("edit_16.png"); //$NON-NLS-1$ - addIcon = Helper.getImage("add_16.png"); //$NON-NLS-1$ - deleteIcon = Helper.getImage("delete_16.png"); //$NON-NLS-1$ - lockUsersIcon = Helper.getImage("lock_users_16.png"); //$NON-NLS-1$ - updateIcon = Helper.getImage("update.png"); //$NON-NLS-1$ favoritesIcon = Helper.getImage("favorites.png"); //$NON-NLS-1$ sortIcon = Helper.getImage("sort.png"); //$NON-NLS-1$ moveUpIcon = Helper.getImage("move_up.png"); //$NON-NLS-1$ moveDownIcon = Helper.getImage("move_down.png"); //$NON-NLS-1$ - LOGGER.info("Icon init succesfully"); //$NON-NLS-1$ + watchSession = Helper.getImage("watch.png"); // $NON-NLS-1$ + roubleIcon = Helper.getImage("Rouble.png"); // $NON-NLS-1$ + + LOGGER.debug("Icon init succesfully"); //$NON-NLS-1$ } private void initToolbar(ToolBar toolBar) { @@ -291,15 +402,23 @@ private void initToolbar(ToolBar toolBar) { toolBar.setSize(-1, 48); addToolbarItem = - addItemInToolbar(toolBar, Strings.CONTEXT_MENU_CREATE, addIcon, toolbarListener); + addItemInToolbar(toolBar, Strings.CONTEXT_MENU_ADD, addIcon24, toolbarListener); editToolbarItem = - addItemInToolbar(toolBar, Strings.CONTEXT_MENU_EDIT, editIcon, toolbarListener); + addItemInToolbar(toolBar, Strings.CONTEXT_MENU_EDIT, editIcon24, toolbarListener); deleteToolbarItem = - addItemInToolbar(toolBar, Strings.CONTEXT_MENU_DELETE, deleteIcon, toolbarListener); + addItemInToolbar(toolBar, Strings.CONTEXT_MENU_DELETE, deleteIcon24, toolbarListener); new ToolItem(toolBar, SWT.SEPARATOR); - addItemInToolbar(toolBar, Strings.CONTEXT_MENU_UPDATE, updateIcon, updateTablesListener); + // addItemInToolbar(toolBar, Strings.CONTEXT_MENU_UPDATE, updateIcon, updateTablesListener); + + ToolItem refreshToolbarItem = new ToolItem(toolBar, SWT.DROP_DOWN); + refreshToolbarItem.setText(Strings.CONTEXT_MENU_UPDATE); + refreshToolbarItem.setImage(updateIcon24); + + refreshTablesListener = new RefreshTablesSelectionListener(refreshToolbarItem); + + toolBar.pack(); } private void initMainMenu(Menu mainMenu) { @@ -309,8 +428,7 @@ private void initMainMenu(Menu mainMenu) { } Menu serversGroup = addItemGroupInMenu(mainMenu, Strings.MENU_SERVERS, null); - addItemInMenu(serversGroup, Strings.MENU_FIND_SERVERS, null, findNewServersListener) - .setEnabled(false); + addItemInMenu(serversGroup, Strings.MENU_FIND_SERVERS, null, findNewServersListener); addItemInMenu(serversGroup, Strings.MENU_CONNECT_ALL_SERVERS, null, connectAllServersListener); addItemInMenu( serversGroup, Strings.MENU_DISCONNECT_ALL_SERVERS, null, disconnectAllServersListener); @@ -318,6 +436,15 @@ private void initMainMenu(Menu mainMenu) { Menu serviceGroup = addItemGroupInMenu(mainMenu, Strings.MENU_SERVICE, null); addItemInMenu(serviceGroup, Strings.MENU_OPEN_SETTINGS, null, openSettingsListener); addItemInMenu(serviceGroup, Strings.MENU_ABOUT, null, showAboutDialogListener); + + SelectionAdapter goToLinkListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + Program.launch(Helper.BOOSTY_LINK); + } + }; + addItemInMenu(serviceGroup, Strings.MENU_DONATE, roubleIcon, goToLinkListener); } private void initServersTree(SashForm sashForm) { @@ -341,25 +468,39 @@ public void handleEvent(Event event) { columnServer.setText(Strings.COLUMN_SERVER); columnServer.setWidth(350); + // Заполнение списка серверов + config + .getServers() + .forEach( + (serverKey, server) -> { + addServerItemInServersTree(server); + }); + columnServer.pack(); } private void initServersTreeContextMenu() { - // Server Menu - serverMenu = new Menu(serversTree); - initServerMenu(); initClusterMenu(); initWorkingServerMenu(); initInfobaseNodeMenu(); initInfobaseMenu(); + // соответствие контекстных меню дерева серверов + serversTreeContextMenus.put(TreeItemType.SERVER, serverMenu); + serversTreeContextMenus.put(TreeItemType.CLUSTER, clusterMenu); + serversTreeContextMenus.put(TreeItemType.INFOBASE_NODE, infobaseNodeMenu); + serversTreeContextMenus.put(TreeItemType.INFOBASE, infobaseMenu); + serversTreeContextMenus.put(TreeItemType.WORKINGSERVER, workingServerMenu); + // set active menu serversTree.setMenu(serverMenu); } private void initServerMenu() { + serverMenu = new Menu(serversTree); + // установка активности элементов контекстного меню serverMenu.addListener(SWT.Show, setActiveConnectActionListener); @@ -392,9 +533,14 @@ private void initServerMenu() { addMenuSeparator(serverMenu); - addItemInMenu(serverMenu, Strings.CONTEXT_MENU_ADD_SERVER, addIcon, addServerListener); - addItemInMenu(serverMenu, Strings.CONTEXT_MENU_EDIT_SERVER, editIcon, editServerListener); - addItemInMenu(serverMenu, Strings.CONTEXT_MENU_UPDATE, updateIcon, updateServerListener); + addItemInMenu(serverMenu, Strings.CONTEXT_MENU_ADD, addIcon16, addServerListener); + addItemInMenu(serverMenu, Strings.CONTEXT_MENU_EDIT, editIcon16, editServerListener); + addItemInMenu(serverMenu, Strings.CONTEXT_MENU_UPDATE, updateIcon16, updateServerListener); + + addMenuSeparator(serverMenu); + MenuItem adminsItem = + addItemInMenu(serverMenu, Strings.CONTEXT_MENU_ADMINS, null, editAdminsListener); + adminsItem.setData("disconnectItem", true); addMenuSeparator(serverMenu); @@ -405,19 +551,35 @@ private void initServerMenu() { addMenuSeparator(serverMenu); - addItemInMenu(serverMenu, Strings.CONTEXT_MENU_REMOVE_SERVER, deleteIcon, deleteServerListener); + addItemInMenu(serverMenu, Strings.CONTEXT_MENU_DELETE, deleteIcon16, deleteServerListener); + } private void initClusterMenu() { clusterMenu = new Menu(serversTree); - addItemInMenu(clusterMenu, Strings.CONTEXT_MENU_CREATE_CLUSTER, addIcon, createClusterListener); - addItemInMenu(clusterMenu, Strings.CONTEXT_MENU_EDIT_CLUSTER, editIcon, editClusterListener); - addItemInMenu(clusterMenu, Strings.CONTEXT_MENU_UPDATE, updateIcon, updateClusterListener); + addItemInMenu( + clusterMenu, Strings.CONTEXT_MENU_CREATE_CLUSTER, addIcon16, createClusterListener); + addItemInMenu(clusterMenu, Strings.CONTEXT_MENU_EDIT_CLUSTER, editIcon16, editClusterListener); + addItemInMenu(clusterMenu, Strings.CONTEXT_MENU_UPDATE, updateIcon16, updateClusterListener); + + addMenuSeparator(clusterMenu); + addItemInMenu(clusterMenu, Strings.CONTEXT_MENU_ADMINS, null, editAdminsListener); + + addMenuSeparator(clusterMenu); + addItemInMenu( + clusterMenu, Strings.CONTEXT_MENU_DELETE_CLUSTER, deleteIcon16, deleteClusterListener); + + addMenuSeparator(clusterMenu); + addItemInMenu( + clusterMenu, Strings.CONTEXT_MENU_RESTART_PROCESSES, null, restartWorkingProcessesListener); + addMenuSeparator(clusterMenu); addItemInMenu( - clusterMenu, Strings.CONTEXT_MENU_DELETE_CLUSTER, deleteIcon, deleteClusterListener); + clusterMenu, Strings.CONTEXT_MENU_APPLY_PARTIAL_RULE, null, applyAssignmentRuleListener, 0); + addItemInMenu( + clusterMenu, Strings.CONTEXT_MENU_APPLY_FULL_RULE, null, applyAssignmentRuleListener, 1); } private void initWorkingServerMenu() { @@ -427,13 +589,13 @@ private void initWorkingServerMenu() { addItemInMenu( workingServerMenu, Strings.CONTEXT_MENU_CREATE_WORKING_SERVER, - addIcon, + addIcon16, createWorkingServerListenerInTree); addItemInMenu( workingServerMenu, Strings.CONTEXT_MENU_EDIT_WORKING_SERVER, - editIcon, + editIcon16, editWorkingServerListenerInTree); } @@ -442,12 +604,12 @@ private void initInfobaseNodeMenu() { infobaseNodeMenu = new Menu(serversTree); addItemInMenu( - infobaseNodeMenu, Strings.CONTEXT_MENU_CREATE_INFOBASE, addIcon, createInfobaseListener); + infobaseNodeMenu, Strings.CONTEXT_MENU_CREATE_INFOBASE, addIcon16, createInfobaseListener); addItemInMenu( infobaseNodeMenu, Strings.CONTEXT_MENU_UPDATE_INFOBASES, - updateIcon, + updateIcon16, updateInfobasesListener); // группа вложенного меню @@ -484,12 +646,13 @@ private void initInfobaseMenu() { infobaseMenu.addListener(SWT.Show, setActiveInfobaseFavoritesActionListener); addItemInMenu( - infobaseMenu, Strings.CONTEXT_MENU_COPY_INFOBASE, addIcon, createInfobaseListener); + infobaseMenu, Strings.CONTEXT_MENU_COPY_INFOBASE, addIcon16, createInfobaseListener); - addItemInMenu(infobaseMenu, Strings.CONTEXT_MENU_EDIT_INFOBASE, editIcon, editInfobaseListener); + addItemInMenu( + infobaseMenu, Strings.CONTEXT_MENU_EDIT_INFOBASE, editIcon16, editInfobaseListener); addItemInMenu( - infobaseMenu, Strings.CONTEXT_MENU_DELETE_INFOBASE, deleteIcon, deleteInfobaseListener); + infobaseMenu, Strings.CONTEXT_MENU_DELETE_INFOBASE, deleteIcon16, deleteInfobaseListener); addMenuSeparator(infobaseMenu); @@ -518,30 +681,55 @@ private void initInfobaseMenu() { Strings.CONTEXT_MENU_TERMINATE_USERS_SESSIONS, null, terminateUsersSessionsListener); - } - private TabItem initListTable( - TabFolder tabFolder, Class clazz, boolean checkable) { + new UserScriptRunner(infobaseMenu); + + // Меню действий с базой + addMenuSeparator(infobaseMenu); + + Menu subMenuInfobaseActions = addItemGroupInMenu(infobaseMenu, Strings.CONTEXT_MENU_INFOBASE_ACTIONS, null); + + addItemInMenu(subMenuInfobaseActions, Strings.CONTEXT_MENU_RUN_ENTERPRISE, null, launchV8ActionListener, V8ActionVariant.RUN_ENTERPRISE); + addItemInMenu(subMenuInfobaseActions, Strings.CONTEXT_MENU_RUN_DESIGNER, null, launchV8ActionListener, V8ActionVariant.RUN_DESIGNER); + + addMenuSeparator(subMenuInfobaseActions); + addItemInMenu(subMenuInfobaseActions, Strings.CONTEXT_MENU_DUMP_CF, null, launchV8ActionListener, V8ActionVariant.DUMP_CF); + addItemInMenu(subMenuInfobaseActions, Strings.CONTEXT_MENU_LOAD_CF, null, launchV8ActionListener, V8ActionVariant.LOAD_CF); - TabItem newTab = new TabItem(tabFolder, SWT.NONE); + addMenuSeparator(subMenuInfobaseActions); + addItemInMenu(subMenuInfobaseActions, Strings.CONTEXT_MENU_DUMP_DT, null, launchV8ActionListener, V8ActionVariant.DUMP_DT); + addItemInMenu(subMenuInfobaseActions, Strings.CONTEXT_MENU_LOAD_DT, null, launchV8ActionListener, V8ActionVariant.LOAD_DT); + } + + private Table initTable(Composite composite, Class clazz) { int style = - checkable + clazz == SessionInfoExtended.class ? SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.CHECK : SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI; - Table table = new Table(tabFolder, style); - newTab.setControl(table); + Table table = new Table(composite, style); + // tabItem.setControl(table); + table.setData(clazz); table.setHeaderVisible(true); table.setLinesVisible(true); table.addKeyListener(tableKeyPressedListener); table.addMouseListener(tablesMouseClickListener); - if (checkable) { + if (clazz == SessionInfoExtended.class) { table.addListener(SWT.Selection, switchWatchingListener); } + table.addFocusListener( + new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + currentTable = table; + // currentTable = (Table) e.widget; + LOGGER.debug("currentTable = {}", currentTable.getData().toString()); + } + }); - ColumnProperties columnProperties = getColumnProperties(clazz); + final ColumnProperties columnProperties = getColumnProperties(clazz); String[] columnNameList = columnProperties.getColumnsDescription(); for (String columnName : columnNameList) { @@ -553,40 +741,248 @@ private TabItem initListTable( table.setColumnOrder(columnOrder); } - BaseInfoExtended.linkTabItem(clazz, newTab); - return newTab; + if (clazz != IAssignmentRuleInfo.class) { + initTableContextMenu(table, clazz); + } + + // BaseInfoExtended.linkTabItem(clazz, tabItem); + return table; + } + + private void initAssRuleTable(SashForm sashWorkingServers) { // таблица с ТНФ + tnfTableViewer = + new TableViewer(sashWorkingServers, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); + tnfTableViewer.setContentProvider(new AssignmentRuleContentProvider()); + + tnfTableViewer.setComparator( + new ViewerComparator() { + public int compare(Viewer viewer, Object e1, Object e2) { + + Table table = ((TableViewer) viewer).getTable(); + TableColumn sortColumn = table.getSortColumn(); + if (sortColumn == null) { + return 0; + } + int numColumn = (int) sortColumn.getData(); + TableViewerColumn tableViewerColumn = + (TableViewerColumn) sortColumn.getData("org.eclipse.jface.columnViewer"); + //TableViewerColumn.class.toString() + + AssignmentRuleLabelProvider labelProvider = + (AssignmentRuleLabelProvider) + tableViewerColumn.getViewer().getLabelProvider(numColumn); + + final Object first; + final Object second; + switch (table.getSortDirection()) { + case SWT.UP: + first = labelProvider.getValue(e1); + second = labelProvider.getValue(e2); + break; + + case SWT.DOWN: + first = labelProvider.getValue(e2); + second = labelProvider.getValue(e1); + break; + + case SWT.NONE: + default: + return 0; + } + if (first instanceof Integer) { + return Integer.compare((int) first, (int) second); + } + if (first instanceof String) { + return ((String) first).compareTo((String) second); + } + return 0; + } + }); + + Table table = tnfTableViewer.getTable(); + + table.setData(IAssignmentRuleInfo.class); + table.setHeaderVisible(true); + table.setLinesVisible(true); + + // tableTnf.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); + table.addKeyListener(tableKeyPressedListener); + table.addMouseListener(tablesMouseClickListener); + table.addFocusListener( + new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + currentTable = table; + // currentTable = (Table) e.widget; + LOGGER.debug("currentTable = {}", currentTable.getData().toString()); + } + }); + + final ColumnProperties columnProperties = getColumnProperties(IAssignmentRuleInfo.class); + + String[] columnNameList = columnProperties.getColumnsName(); // TODO + String[] columnDescList = columnProperties.getColumnsDescription(); + + for (int i = 0; i < columnNameList.length; i++) { + addTableViewerColumn(tnfTableViewer, columnNameList[i], columnDescList[i], columnProperties); + } + + int[] columnOrder = columnProperties.getOrder(); + if (columnOrder != null && table.getColumnCount() == columnOrder.length) { + table.setColumnOrder(columnOrder); + } + } - private void initTableContextMenu( - TabItem tab, boolean updatable, boolean creatable, boolean editable, boolean killable) { - Table table = getTable(tab); + private void initTableContextMenu(Table table, Class clazz) { + + // Table table = getTable(tab); + Menu tableMenu = new Menu(table); table.setMenu(tableMenu); - if (updatable) { - addItemInMenu(tableMenu, Strings.CONTEXT_MENU_UPDATE_F5, updateIcon, updateTablesListener); + // установка активности элементов контекстного меню + + Listener setActiveContextMenuListener = + new Listener() { + @Override + public void handleEvent(Event event) { + + TableItem[] items = currentTable.getSelection(); + boolean selected = (items.length != 0); + + MenuItem[] menuItems = ((Menu) event.widget).getItems(); + + for (MenuItem menuItem : menuItems) { + if (!menuItem.getText().equals(Strings.CONTEXT_MENU_UPDATE_F5) + && !menuItem.getText().equals(Strings.CONTEXT_MENU_ADD_HOTKEY)) { + menuItem.setEnabled(selected); + } + } + } + }; + tableMenu.addListener(SWT.Show, setActiveContextMenuListener); + + final SelectionAdapter refreshListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + currentTable = table; + refreshCurrentList(); + } + }; + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_UPDATE_F5, updateIcon16, refreshListener); + + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_COPY_CELL, null, copyCellValueInTablesListener); + + // у соединений еще есть прерывание серверного вызова (с какой то версии платформы) + if (clazz == WorkingServerInfoExtended.class || clazz == IAssignmentRuleInfo.class) { + + final SelectionAdapter addListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + addItemInTable(table); + } + }; + final SelectionAdapter editListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length == 0) { + return; + } + editItemInTable(items[0]); + } + }; + final SelectionAdapter deleteListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length == 0) { + return; + } + deleteItemsFromTable(items); + } + }; + + addMenuSeparator(tableMenu); + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_ADD_HOTKEY, addIcon16, addListener); + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_EDIT_HOTKEY, editIcon16, editListener); + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_DELETE_HOTKEY, deleteIcon16, deleteListener); + + } else if (clazz == SessionInfoExtended.class) { + // просмотр + final SelectionAdapter viewListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length == 0) { + return; + } + viewItemInTable(items[0]); + } + }; + // TODO для сеансов есть форма, для соединений и раб.процессов - ее нет + // попробовать сделать генерируюмую форму со списком полей + addMenuSeparator(tableMenu); + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_VIEW_HOTKEY, viewIcon16, viewListener); } - if (creatable) { - addItemInMenu( - tableMenu, - Strings.CONTEXT_MENU_CREATE_WORKING_SERVER, - addIcon, - createWorkingServerListener); + if (clazz == SessionInfoExtended.class) { + addItemInMenu( + tableMenu, Strings.CONTEXT_MENU_WATCH_SESSION, watchSession, switchWatchingMenuListener); } - if (editable) { - String title = tableContextItemEdit.get(tab); - addItemInMenu(tableMenu, title, editIcon, editItemInTablesListener); + if (clazz == SessionInfoExtended.class || clazz == ConnectionInfoExtended.class) { + final SelectionAdapter deleteListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length == 0) { + return; + } + deleteItemsFromTable(items); + } + }; + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_DELETE_HOTKEY, deleteIcon16, deleteListener); } - if (killable) { - String title = tableContextItemDelete.get(tab); - addItemInMenu(tableMenu, title, deleteIcon, deleteItemInTablesListener); + if (clazz == IAssignmentRuleInfo.class) { + // пункты увеличения и уменьшения порядка правила ТНФ + final SelectionAdapter increaseListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length == 0) { + return; + } + changeAssignmentRuleNumber(items[0], true); + } + }; + final SelectionAdapter reduseListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + TableItem[] items = table.getSelection(); + if (items.length == 0) { + return; + } + changeAssignmentRuleNumber(items[0], false); + } + }; + addMenuSeparator(tableMenu); + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_MOVE_UP, moveUpIcon, increaseListener); + addItemInMenu(tableMenu, Strings.CONTEXT_MENU_MOVE_DOWN, moveDownIcon, reduseListener); } } - private void initMaps() { + private void initToolbarListeners() { // обработчики кнопки тулбара "Добавить" toolbarCreateListeners.put(TreeItemType.SERVER, addServerListener); @@ -607,32 +1003,12 @@ private void initMaps() { toolbarDeleteListeners.put(TreeItemType.CLUSTER, deleteClusterListener); toolbarDeleteListeners.put(TreeItemType.INFOBASE, deleteInfobaseListener); - // контекстные меню дерева серверов - serversTreeContextMenus.put(TreeItemType.SERVER, serverMenu); - serversTreeContextMenus.put(TreeItemType.CLUSTER, clusterMenu); - serversTreeContextMenus.put(TreeItemType.INFOBASE_NODE, infobaseNodeMenu); - serversTreeContextMenus.put(TreeItemType.INFOBASE, infobaseMenu); - serversTreeContextMenus.put(TreeItemType.WORKINGSERVER, workingServerMenu); - - // тексты пунктов контекстного меню списков - tableContextItemEdit.put(tabSessions, Strings.CONTEXT_MENU_VIEW_SESSION_F2); - tableContextItemEdit.put(tabWorkingServers, Strings.CONTEXT_MENU_EDIT_WORKING_SERVER_F2); - tableContextItemDelete.put(tabSessions, Strings.CONTEXT_MENU_KILL_SESSION_DEL); - tableContextItemDelete.put(tabConnections, Strings.CONTEXT_MENU_KILL_CONNECTION_DEL); - tableContextItemDelete.put(tabWorkingServers, Strings.CONTEXT_MENU_DELETE_WORKING_SERVER_DEL); - - // соответствие таблиц списков - linksTablesToExtendedClass.put(tabSessions, SessionInfoExtended.class); - linksTablesToExtendedClass.put(tabConnections, ConnectionInfoExtended.class); - linksTablesToExtendedClass.put(tabLocks, LockInfoExtended.class); - linksTablesToExtendedClass.put(tabWorkingServers, WorkingServerInfoExtended.class); - linksTablesToExtendedClass.put(tabWorkingProcesses, WorkingProcessInfoExtended.class); } private ToolItem addItemInToolbar( ToolBar parent, String text, Image icon, SelectionAdapter listener) { - ToolItem toolItem = new ToolItem(parent, SWT.PUSH); + ToolItem toolItem = new ToolItem(parent, SWT.PUSH | SWT.WRAP); toolItem.setText(text); toolItem.setImage(icon); toolItem.addSelectionListener(listener); @@ -667,12 +1043,20 @@ private MenuItem addItemInMenu(Menu parent, String text, Image icon, SelectionAd return menuItem; } + private MenuItem addItemInMenu( + Menu parent, String text, Image icon, SelectionAdapter listener, Object data) { + + MenuItem menuItem = new MenuItem(parent, SWT.NONE); // SWT.BOLD + menuItem.setText(text); + menuItem.setImage(icon); + menuItem.addSelectionListener(listener); + menuItem.setData(data); + + return menuItem; + } + private MenuItem addRadioItemInMenu( - Menu parent, - String text, - SelectionAdapter listener, - Object data, - boolean selected) { + Menu parent, String text, SelectionAdapter listener, Object data, boolean selected) { MenuItem menuItem = new MenuItem(parent, SWT.RADIO); menuItem.setText(text); @@ -696,14 +1080,13 @@ private TreeItem addServerItemInServersTree(Server server, int index) { TreeItemType.SERVER, SERVER_INFO, server, - server.isConnected() ? serverConnectedIcon : serverIcon); + server.getTreeImage()); } private TreeItem addClusterItemInServersTree(TreeItem serverItem, IClusterInfo clusterInfo) { Server server = getServer(serverItem); if (server == null) { - LOGGER.error("Error get Server from serverItem"); //$NON-NLS-1$ return null; } @@ -875,14 +1258,19 @@ private void setItemProperties( private void addTableColumn(Table table, String text, ColumnProperties columnProperties) { - final int[] columnWidth = columnProperties.getWidth(); - final boolean[] columnVisible = columnProperties.getVisible(); - var newColumn = new TableColumn(table, SWT.NONE); newColumn.setText(text); newColumn.setMoveable(true); newColumn.setAlignment(SWT.RIGHT); + if (columnProperties == null) { + newColumn.setWidth(100); + return; + } + + final int[] columnWidth = columnProperties.getWidth(); + final boolean[] columnVisible = columnProperties.getVisible(); + int numOfColumn = table.getColumnCount() - 1; newColumn.setData(numOfColumn); if (numOfColumn == columnProperties.getSortColumn()) { @@ -892,11 +1280,7 @@ private void addTableColumn(Table table, String text, ColumnProperties columnPro if (columnVisible != null && columnVisible[numOfColumn]) { newColumn.setResizable(true); - newColumn.setWidth( - // columnWidth == null //TODO нужно ли это еще - // || columnWidth.length <= table.getColumnCount() - // || - columnWidth[numOfColumn] == 0 ? 100 : columnWidth[numOfColumn]); + newColumn.setWidth(columnWidth[numOfColumn] == 0 ? 100 : columnWidth[numOfColumn]); } else { newColumn.setResizable(false); newColumn.setWidth(0); @@ -907,6 +1291,20 @@ private void addTableColumn(Table table, String text, ColumnProperties columnPro newColumn.addListener(SWT.Selection, columnSortListener); } + private void addTaskTableColumn(Table table, String text, int width) { + addTaskTableColumn(table, text, width, SWT.LEFT); + } + + private void addTaskTableColumn(Table table, String text, int width, int alignment) { + + var newColumn = new TableColumn(table, SWT.NONE); + newColumn.setText(text); + newColumn.setMoveable(false); + newColumn.setAlignment(alignment); + newColumn.setResizable(true); + newColumn.setWidth(width); + } + private Server getCurrentServer() { return getServer(currentTreeItem); } @@ -924,7 +1322,8 @@ private UUID getCurrentWorkingServerId() { } private Server getServer(TreeItem item) { - if (item == null) { + if (item == null || item.isDisposed()) { + LOGGER.error("Error get Server from serverItem"); // $NON-NLS-1$ return null; } @@ -941,6 +1340,7 @@ private Server getServer(TreeItem item) { parentItem = parentItem.getParentItem(); } } + LOGGER.error("Error get Server from serverItem"); // $NON-NLS-1$ return null; } @@ -1012,27 +1412,25 @@ private void runAutonnectAllServers() { private void connectServerItem(TreeItem serverItem, boolean silentMode) { - // async не работает асинхронно - serverItem.setImage(serverConnectingIcon); - Display.getDefault() - .asyncExec( - new Runnable() { + Server server = getServer(serverItem); + if (server == null) { + return; + } - @Override - public void run() { + Thread thread = + new Thread( + () -> { + server.connectToServer(false, silentMode); + }); - Server server = getServer(serverItem); - if (server == null) { - return; - } - server.connectToServer(false, silentMode); + thread.start(); - serverItem.setImage( // TODO server.getImage() - server.isConnected() ? serverConnectedIcon : serverDisconnectIcon); - serverItem.setText(new String[] {server.getTreeTitle()}); - updateClustersInTree(serverItem); - } - }); + waitingConnectServers.add(serverItem); + if (serverConnectionTimer == null) { + serverConnectionTimer = new Timer(true); + serverConnectionTimer.schedule(new ServerConnectionCheckerTimer(), 1000, 1000); + } + server.updateTreeItemState(serverItem); } private void disconnectServerItem(TreeItem serverItem) { @@ -1041,16 +1439,9 @@ private void disconnectServerItem(TreeItem serverItem) { return; } server.disconnectFromAgent(); - serverItem.setImage(serverIcon); - - TreeItem[] clusterItems = serverItem.getItems(); - for (TreeItem clusterItem : clusterItems) { - clusterItem.dispose(); - } - } - - private void fillServersList() { - // TODO Auto-generated method stub + server.updateTreeItemState(serverItem); + saveCurrentSelectedData(serverItem); + Arrays.stream(serverItem.getItems()).forEach(Widget::dispose); } private void updateClustersInTree(TreeItem serverItem) { @@ -1096,6 +1487,7 @@ private void updateClustersInTree(TreeItem serverItem) { // Разворачиваем дерево, если включена настройка serverItem.setExpanded(config.isExpandServersTree()); + columnServer.pack(); } private void updateNodesOfCluster(TreeItem clusterItem, Server server) { @@ -1285,9 +1677,8 @@ private void updateNode( UUID clusterId = getClusterId(clusterItem); } - private void fillTabs() { + private void refreshCurrentList() { - Table currentTable = getCurrentTable(); if (currentTable == null) { return; } @@ -1300,40 +1691,55 @@ private void fillTabs() { UUID clusterId = getCurrentClusterId(); UUID infobaseId = getInfobaseId(currentTreeItem); UUID workingProcessId = getCurrentWorkingProcessId(); - TreeItemType treeItemType = getTreeItemType(currentTreeItem); // TODO currentHighlightingType + // TreeItemType treeItemType = getTreeItemType(currentTreeItem); // TODO currentHighlightingType - clearTabs(); + final Class clazz = (Class) currentTable.getData(); + clearTabs(clazz == IAssignmentRuleInfo.class); List list = null; + + // TODO getSessionsExtendedInfo, getConnectionsExtendedInfo и др. // заменить на одну?, определяемую через map - if (currentTab.equals(tabSessions)) { - list = server.getSessionsExtendedInfo(treeItemType, clusterId, workingProcessId, infobaseId); + if (clazz == SessionInfoExtended.class) { + list = + server.getSessionsExtendedInfo( + currentHighlightingType, clusterId, workingProcessId, infobaseId); - } else if (currentTab.equals(tabConnections)) { + } else if (clazz == ConnectionInfoExtended.class) { list = - server.getConnectionsExtendedInfo(treeItemType, clusterId, workingProcessId, infobaseId); + server.getConnectionsExtendedInfo( + currentHighlightingType, clusterId, workingProcessId, infobaseId); + + } else if (clazz == LockInfoExtended.class) { + list = server.getLocksExtendedInfo(currentHighlightingType, clusterId, infobaseId); - } else if (currentTab.equals(tabLocks)) { - list = server.getLocksExtendedInfo(treeItemType, clusterId, infobaseId); + } else if (clazz == WorkingProcessInfoExtended.class) { + list = + server.getWorkingProcessesExtendedInfo( + currentHighlightingType, clusterId, workingProcessId); - } else if (currentTab.equals(tabWorkingProcesses)) { - list = server.getWorkingProcessesExtendedInfo(treeItemType, clusterId, workingProcessId); + } else if (clazz == WorkingServerInfoExtended.class) { + list = server.getWorkingServersExtendedInfo(currentHighlightingType, clusterId); - } else if (currentTab.equals(tabWorkingServers)) { - list = server.getWorkingServersExtendedInfo(treeItemType, clusterId); + // очистка таблицы с ТНФ + tnfTableViewer.getTable().clearAll(); + } else if (clazz == IAssignmentRuleInfo.class) { + fillAssignmentRulesTable(); + return; } else { return; } - BaseInfoExtended.updateTabText(linksTablesToExtendedClass.get(currentTab), list.size()); + BaseInfoExtended.updateTabText((Class) clazz, list.size()); list.forEach(item -> item.addToTable(currentTable)); } private void highlightTreeItem(TreeItem treeItem) { currentTreeItem = treeItem; currentTreeItem.setFont(fontBold); + columnServer.pack(); } private void setActiveContextMenuInTree(TreeItem treeItem) { @@ -1341,20 +1747,20 @@ private void setActiveContextMenuInTree(TreeItem treeItem) { serversTree.setMenu(serversTreeContextMenus.get(currentContextMenuItem)); } - private void clearTabs() { + private void clearTabs(boolean isAssignmentRule) { // BaseInfoExtended.resetTabsTextCount(); - getTable(tabSessions).removeAll(); - getTable(tabConnections).removeAll(); - getTable(tabLocks).removeAll(); - getTable(tabWorkingProcesses).removeAll(); - getTable(tabWorkingServers).removeAll(); + tableSessions.removeAll(); + tableConnections.removeAll(); + tableLocks.removeAll(); + tableWorkingProcesses.removeAll(); + if (!isAssignmentRule) { + tableWorkingServers.removeAll(); + } } private void clickItemInServerTree(int mouseButton) { - // TODO запутанный метод - // его надо переделать, переименовать, переосмыслить места вызова TreeItem[] item = serversTree.getSelection(); if (item.length == 0) { return; @@ -1369,7 +1775,7 @@ private void clickItemInServerTree(int mouseButton) { } saveCurrentSelectedData(treeItem); setEnableToolbarItems(); - fillTabs(); + refreshCurrentList(); break; case 3: // right click @@ -1382,22 +1788,25 @@ private void clickItemInServerTree(int mouseButton) { } private Table getCurrentTable() { - // return linksTabToTables.get(currentTab); - return ((Table) currentTab.getControl()); + return currentTable; } private Table getTable(TabItem tab) { - return ((Table) tab.getControl()); + Control control = tab.getControl(); + if (control instanceof Table) { + return (Table) control; + } + if (control instanceof SashForm) { + return (Table) (((SashForm) control).getChildren())[0]; + } + // return ((Table) tab.getControl()); + return null; } - private ColumnProperties getColumnProperties(Class clazz) { + private ColumnProperties getColumnProperties(Class clazz) { return config.getColumnsProperties(clazz); } - private ColumnProperties getColumnProperties(TabItem tab) { - return config.getColumnsProperties(linksTablesToExtendedClass.get(tab)); - } - private void saveCurrentSelectedData(TreeItem treeItem) { if (currentTreeItem != null && !currentTreeItem.isDisposed()) { @@ -1440,31 +1849,441 @@ private void saveCurrentSelectedData(TreeItem treeItem) { private void setEnableToolbarItems() { // включение/выключение активности кнопок тулбара - addToolbarItem.setEnabled(toolbarCreateListeners.get(currentHighlightingType) != null); + addToolbarItem.setEnabled( + serversTree.getSelection().length == 0 + || toolbarCreateListeners.get(currentHighlightingType) != null); + editToolbarItem.setEnabled(toolbarEditListeners.get(currentHighlightingType) != null); deleteToolbarItem.setEnabled(toolbarDeleteListeners.get(currentHighlightingType) != null); } - ////////////////////////////////////////////////////////////////////////// - // LISTENERS + private void fillAssignmentRulesTable() { + Object wsInfo = tnfTableViewer.getTable().getData(ID_DATA_KEY); + fillAssignmentRulesTable((WorkingServerInfoExtended) wsInfo); + } - MouseAdapter treeItemMouseClickListener = - new MouseAdapter() { - @Override - public void mouseDown(MouseEvent e) { - clickItemInServerTree(e.button); - } + private void fillAssignmentRulesTable(WorkingServerInfoExtended wsInfo) { - @Override - public void mouseDoubleClick(MouseEvent e) { - TreeItem[] items = ((Tree) e.widget).getSelection(); - if (items.length == 0) { - return; - } + TableItem[] item = tableWorkingServers.getSelection(); + if (item.length == 0) { + return; + } + Server server = getCurrentServer(); + UUID clusterId = getCurrentClusterId(); + UUID workingServerId = wsInfo.getWorkingServerId(); + if (server == null || clusterId == null) { + return; + } - SelectionAdapter listener = toolbarEditListeners.get(currentHighlightingType); - if (listener != null) { - listener.widgetSelected(null); + // Заполнение таблицы с ТНФ + List listTnf = server.getAssignmentRules(clusterId, workingServerId); + tnfTableViewer.setInput(listTnf); + tnfTableViewer.getTable().setData(ID_DATA_KEY, wsInfo); + } + + private void addTableViewerColumn( + TableViewer tableViewer, String name, String desc, ColumnProperties columnProperties) { + + var tableViewerColumnParamKey = new TableViewerColumn(tableViewer, SWT.NONE); + TableColumn newColumn = tableViewerColumnParamKey.getColumn(); + newColumn.setText(desc); + newColumn.setMoveable(true); + newColumn.setAlignment(SWT.RIGHT); + tableViewerColumnParamKey.setLabelProvider(new AssignmentRuleLabelProvider(name)); + + if (columnProperties == null) { + newColumn.setWidth(100); + return; + } + + final int[] columnWidth = columnProperties.getWidth(); + final boolean[] columnVisible = columnProperties.getVisible(); + + Table table = tableViewer.getTable(); + int numOfColumn = table.getColumnCount() - 1; + newColumn.setData(numOfColumn); + if (numOfColumn == columnProperties.getSortColumn()) { + table.setSortColumn(newColumn); + table.setSortDirection(columnProperties.getSortDirectionSwt()); + } + + if (columnVisible != null && columnVisible[numOfColumn]) { + newColumn.setResizable(true); + newColumn.setWidth(columnWidth[numOfColumn] == 0 ? 100 : columnWidth[numOfColumn]); + } else { + newColumn.setResizable(false); + newColumn.setWidth(0); + } + + newColumn.addListener(SWT.Move, columnMoveListener); + newColumn.addListener(SWT.Resize, columnResizeListener); + newColumn.addListener(SWT.Selection, columnSortListener); + } + + private void addItemInTable(Table table) { + Class clazz = (Class) table.getData(); + + if (clazz == WorkingServerInfoExtended.class) { + + Server server = getCurrentServer(); + UUID clusterId = getCurrentClusterId(); + + if (server == null || clusterId == null) { + return; + } + + WorkingServerDialog dialog; + try { + dialog = + new WorkingServerDialog( + getParent().getDisplay().getActiveShell(), server, clusterId, null); + } catch (Exception excp) { + LOGGER.error( + "Error init WorkingServerDialog for cluster id {}", //$NON-NLS-1$ + clusterId, + excp); + return; + } + + if (dialog.open() == 0) { + refreshCurrentList(); + } + } + + if (clazz == IAssignmentRuleInfo.class) { + + WorkingServerInfoExtended wsInfo = (WorkingServerInfoExtended) table.getData(ID_DATA_KEY); + + Server server = getCurrentServer(); + UUID clusterId = getCurrentClusterId(); + UUID wsId = wsInfo.getWorkingServerId(); + if (server == null || clusterId == null || wsId == null) { + return; + } + + AssignmentRuleDialog dialog; + try { + dialog = + new AssignmentRuleDialog( + getParent().getDisplay().getActiveShell(), server, clusterId, wsId, null); + } catch (Exception excp) { + excp.printStackTrace(); + LOGGER.error( + "Error init AssignmentRuleEditDialog for new rule", //$NON-NLS-1$ + excp); + return; + } + + if (dialog.open() == 0) { + fillAssignmentRulesTable(); + } + } + + } + + private void viewItemInTable(TableItem item) { + BaseInfoExtended extInfo = (BaseInfoExtended) item.getData(EXTENDED_INFO); + + if (extInfo instanceof SessionInfoExtended) { + + SessionInfoExtended sessionExtInfo = (SessionInfoExtended) extInfo; + + SessionInfoDialog dialog; + try { + dialog = new SessionInfoDialog(getParent().getDisplay().getActiveShell(), sessionExtInfo); + } catch (Exception excp) { + excp.printStackTrace(); + LOGGER.error( + "Error init SessionInfoDialog for session id {}", //$NON-NLS-1$ + sessionExtInfo.getSessionInfo().getSid(), + excp); + return; + } + + dialog.open(); + } + } + + private void editItemInTable(TableItem item) { + BaseInfoExtended extInfo = (BaseInfoExtended) item.getData(EXTENDED_INFO); + if (extInfo instanceof WorkingServerInfoExtended) { + + WorkingServerInfoExtended workingServerExtInfo = (WorkingServerInfoExtended) extInfo; + + WorkingServerDialog dialog; + try { + dialog = + new WorkingServerDialog( + getParent().getDisplay().getActiveShell(), workingServerExtInfo); + } catch (Exception excp) { + excp.printStackTrace(); + LOGGER.error( + "Error init WorkingServerDialog for cluster id {}", //$NON-NLS-1$ + workingServerExtInfo.getWorkingServerId(), + excp); + return; + } + + if (dialog.open() == 0) { + // clickItemInServerTree(0); // TODO что здесь должно делаться??? + refreshCurrentList(); + } + } else if (extInfo == null && item.getData() instanceof IAssignmentRuleInfo) { + IAssignmentRuleInfo ruleInfo = (IAssignmentRuleInfo) item.getData(); + + WorkingServerInfoExtended wsInfo = + (WorkingServerInfoExtended) item.getParent().getData(ID_DATA_KEY); + + Server server = getCurrentServer(); + UUID clusterId = getCurrentClusterId(); + UUID wsId = wsInfo.getWorkingServerId(); + if (server == null || clusterId == null || wsId == null) { + return; + } + + AssignmentRuleDialog dialog; + try { + dialog = + new AssignmentRuleDialog( + getParent().getDisplay().getActiveShell(), server, clusterId, wsId, ruleInfo); + } catch (Exception excp) { + excp.printStackTrace(); + LOGGER.error( + "Error init AssignmentRuleEditDialog for rule {}", //$NON-NLS-1$ + ruleInfo.getObjectType(), + excp); + return; + } + + if (dialog.open() == 0) { + refreshCurrentList(); + } + + } else { + return; + } + } + + private void deleteItemsFromTable(TableItem[] selectedItems) { + + for (TableItem item : selectedItems) { + + Object extInfo = item.getData(EXTENDED_INFO); + item.setForeground(deletedItemColor); // TODO успевает ли окраситься в красный цвет + + if (extInfo instanceof SessionInfoExtended) { + SessionInfoExtended sessionExtInfo = (SessionInfoExtended) extInfo; + + Server server = sessionExtInfo.getServer(); + UUID clusterId = sessionExtInfo.getClusterId(); + UUID sessionId = sessionExtInfo.getSessionInfo().getSid(); + + if (server.terminateSession(clusterId, sessionId)) { + item.dispose(); + } + + } else if (extInfo instanceof ConnectionInfoExtended) { + ConnectionInfoExtended connExtInfo = (ConnectionInfoExtended) extInfo; + + Server server = connExtInfo.getServer(); + UUID clusterId = connExtInfo.getClusterId(); + UUID processId = connExtInfo.getConnectionInfo().getWorkingProcessId(); + UUID connectionId = connExtInfo.getConnectionInfo().getInfoBaseConnectionId(); + UUID infobaseId = connExtInfo.getConnectionInfo().getInfoBaseId(); + + if (server.disconnectConnection(clusterId, processId, connectionId, infobaseId)) { + item.dispose(); // update tableConnections + } + + } else if (extInfo instanceof WorkingServerInfoExtended) { + WorkingServerInfoExtended wsExtInfo = (WorkingServerInfoExtended) extInfo; + + Server server = wsExtInfo.getServer(); + UUID clusterId = wsExtInfo.getClusterId(); + UUID workingServerId = wsExtInfo.getWorkingServerId(); + + int answer = + Helper.showQuestionBox( + Messages.getString("ViewerArea.DeleteServerQuestion")); // $NON-NLS-1$ + + if (answer == SWT.YES && server.unregWorkingServer(clusterId, workingServerId)) { + item.dispose(); // update tableWorkingServers + } + } else if (extInfo == null && item.getData() instanceof IAssignmentRuleInfo) { + IAssignmentRuleInfo ruleInfo = (IAssignmentRuleInfo) item.getData(); + + WorkingServerInfoExtended wsInfo = + (WorkingServerInfoExtended) item.getParent().getData(ID_DATA_KEY); + + Server server = getCurrentServer(); + UUID clusterId = getCurrentClusterId(); + UUID wsId = wsInfo.getWorkingServerId(); + if (server == null || clusterId == null || wsId == null) { + return; + } + + int answer = + Helper.showQuestionBox( + Messages.getString("ViewerArea.DeleteAssignmentRule")); // $NON-NLS-1$ + + if (answer == SWT.YES + && server.unregAssignmentRule(clusterId, wsId, ruleInfo.getAssignmentRuleId())) { + item.dispose(); + } + + } else { + break; + } + } + } + + private void changeAssignmentRuleNumber(TableItem item, boolean increase) { + IAssignmentRuleInfo rule = (IAssignmentRuleInfo) item.getData(); + + int newRuleNumber = AssignmentRuleContentProvider.getRuleNumber(rule) + (increase ? -1 : 1); + + WorkingServerInfoExtended wsInfo = + (WorkingServerInfoExtended) item.getParent().getData(ID_DATA_KEY); + + Server server = getCurrentServer(); + UUID clusterId = getCurrentClusterId(); + UUID wsId = wsInfo.getWorkingServerId(); + if (server == null || clusterId == null || wsId == null) { + return; + } + + server.regAssignmentRule(clusterId, wsId, rule, newRuleNumber - 1); + refreshCurrentList(); + } + + private Map fillParams(BackgroundTask backgroundTask, TreeItem infobaseItem) { + Map params = new LinkedHashMap<>(); + + UUID clusterId = getClusterId(infobaseItem); + UUID infobaseId = getInfobaseId(infobaseItem); + Server server = getServer(infobaseItem); + if (server == null) { + LOGGER.error( + "Error get server info {}", //$NON-NLS-1$ + backgroundTask.getScriptName()); + return params; + } + + boolean foundEmptyParams = false; + boolean foundUsernameParam = false; + boolean foundPasswordParam = false; + + Pattern p = Pattern.compile("\\%.+?\\%"); + // Pattern p = Pattern.compile("[^\\%]++", Pattern.CASE_INSENSITIVE); + + Matcher m = p.matcher(backgroundTask.getScriptText()); + while (m.find()) { + final String foundParam = m.group(); + String paramValue; + + switch (foundParam) { + case "%v8infobase%": + paramValue = server.getInfoBaseName(clusterId, infobaseId); + break; + + case "%v8serverName%": + paramValue = server.getAgentHost(); + break; + + case "%v8agentPort%": + paramValue = server.getAgentPortAsString(); + break; + + case "%v8managerPort%": + paramValue = server.getClusterMainPort(clusterId); + break; + + case "%v8version%": + paramValue = server.getV8Version(); + break; + + case "%v8username%": + foundUsernameParam = true; + foundEmptyParams = true; + continue; + + case "%v8password%": + foundPasswordParam = true; + foundEmptyParams = true; + continue; + + default: + LOGGER.info("Found unknown param {}", foundParam); + paramValue = ""; + foundEmptyParams = true; + break; + } + + String paramKey = foundParam.replace("%", ""); + params.put(paramKey, paramValue); + } + if (Boolean.TRUE.equals(foundUsernameParam)) { + params.put("v8username", ""); + } + if (Boolean.TRUE.equals(foundPasswordParam)) { + params.put("v8password", ""); + } + + if (foundEmptyParams) { + BackgroundTaskParams taskParamsDialog = + new BackgroundTaskParams( + getShell(), + params, + backgroundTask, + server.getInfobasesCredentials()); + int dialogResult = taskParamsDialog.open(); + if (dialogResult != 0) { + return new HashMap<>(); + } + + params = taskParamsDialog.getParams(); + } + + return params; + } + + private void addToTasksQueue(BackgroundTask task) { + TableItem tableItem = new TableItem(tableTasks, SWT.NONE); + tableItem.setData(task); + tableItem.setChecked(false); + + if (tableTasks.getSelection().length == 0 || BackgroundTask.getRunningCount() == 0) { + tableTasks.setSelection(tableItem); + } + + task.run(); + + if (BackgroundTask.getRunningCount() == 0) { + taskTimer = new Timer(true); + taskTimer.scheduleAtFixedRate(new TaskChekerTimer(), 1000, 1000); + } + } + + ////////////////////////////////////////////////////////////////////////// + // LISTENERS + + MouseAdapter treeItemMouseClickListener = + new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + clickItemInServerTree(e.button); + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + TreeItem[] items = ((Tree) e.widget).getSelection(); + if (items.length == 0) { + return; + } + + SelectionAdapter listener = toolbarEditListeners.get(currentHighlightingType); + if (listener != null) { + listener.widgetSelected(null); } } }; @@ -1511,9 +2330,22 @@ public void widgetSelected(SelectionEvent e) { new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - List newServers = clusterProvider.findNewServers(); - if (!newServers.isEmpty()) { - fillServersList(); + NewServersChoiseDialog dialog; + try { + dialog = new NewServersChoiseDialog(getParent().getDisplay().getActiveShell()); + } catch (Exception excp) { + LOGGER.error("Error init NewServersChoiseDialog", excp); // $NON-NLS-1$ + return; + } + + if (dialog.open() == 0) { + List s = dialog.getNewServers(); + if (s.isEmpty()) { + return; + } + + Config.currentConfig.addNewServers(s); + s.forEach((server) -> addServerItemInServersTree(server)); } } }; @@ -1623,9 +2455,7 @@ public void widgetSelected(SelectionEvent event) { return; } - var messageBox = new MessageBox(Display.getDefault().getActiveShell()); - messageBox.setMessage(server.getConnectionError()); - messageBox.open(); + Helper.showMessageBox(server.getConnectionError()); } }; @@ -1634,23 +2464,24 @@ public void widgetSelected(SelectionEvent event) { @Override public void widgetSelected(SelectionEvent event) { - if (currentHighlightingType == null) { // пустое дерево + String buttonName = ((ToolItem) event.widget).getText(); + + if (serversTree.getSelection().length == 0 + && Strings.CONTEXT_MENU_ADD.equals(buttonName)) { addServerListener.widgetSelected(event); return; } - TreeItem[] item = serversTree.getSelection(); - if (item.length == 0) { + if (currentHighlightingType == null) { // пустое дерево или ничего не выбрано return; } Map currListener = null; - String text = ((ToolItem) event.widget).getText(); - if (Strings.CONTEXT_MENU_CREATE.equals(text)) { + if (Strings.CONTEXT_MENU_ADD.equals(buttonName)) { currListener = toolbarCreateListeners; - } else if (Strings.CONTEXT_MENU_EDIT.equals(text)) { + } else if (Strings.CONTEXT_MENU_EDIT.equals(buttonName)) { currListener = toolbarEditListeners; - } else if (Strings.CONTEXT_MENU_DELETE.equals(text)) { + } else if (Strings.CONTEXT_MENU_DELETE.equals(buttonName)) { currListener = toolbarDeleteListeners; } else { return; @@ -1930,7 +2761,7 @@ public void widgetSelected(SelectionEvent event) { int dialogResult = dialog.open(); if (dialogResult == 0) { - updateClustersInTree(item[0]); + updateClustersInTree(item[0].getParentItem()); } } }; @@ -1975,6 +2806,121 @@ public void widgetSelected(SelectionEvent event) { } }; + SelectionAdapter editAdminsListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + TreeItem[] item = serversTree.getSelection(); + if (item.length == 0) { + return; + } + TreeItem treeItem = item[0]; + TreeItemType treeItemType = getTreeItemType(treeItem); + if (treeItemType != TreeItemType.SERVER && treeItemType != TreeItemType.CLUSTER) { + LOGGER.error("Invalid item type for AdminsDialog"); // $NON-NLS-1$ + return; + } + + Server server = getServer(treeItem); + UUID clusterId = getClusterId(treeItem); + + AdminsDialog dialog; + try { + dialog = new AdminsDialog(getParent().getDisplay().getActiveShell(), server, clusterId); + } catch (Exception excp) { + LOGGER.error( + "Error init AdminsDialog for cluster id {}", //$NON-NLS-1$ + clusterId, + excp); + return; + } + dialog.open(); + } + }; + + SelectionAdapter restartWorkingProcessesListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + TreeItem[] item = serversTree.getSelection(); + if (item.length == 0) { + return; + } + final TreeItem clusterItem = item[0]; + + Server server = getServer(clusterItem); + UUID clusterId = getClusterId(clusterItem); + if (server == null || clusterId == null) { + return; + } + + if (!server.checkAutenticateAgent()) { + Helper.showMessageBox(Strings.ERROR_AUTH_FOR_RESTART_WP); + return; + } + + Thread thread = + new Thread( + () -> { + IClusterInfo clusterInfo = server.getClusterInfo(clusterId); + + final int oldLifeTimeLimit = clusterInfo.getLifeTimeLimit(); + final boolean oldRecyclingKillProcesses = + clusterInfo.isClusterRecyclingKillProblemProcesses(); + final int oldExpirationTimeout = clusterInfo.getExpirationTimeout(); + + clusterInfo.setLifeTimeLimit(10); + clusterInfo.setClusterRecyclingKillProblemProcesses(true); + clusterInfo.setExpirationTimeout(20); + + if (!server.regCluster(clusterInfo)) { + Helper.showMessageBox("Error setting temporary properties for the cluster"); + return; + } + + // подождать 10 секунд и вернуть все назад + try { + Thread.sleep(10000); + } catch (InterruptedException excp) { + LOGGER.error("Error: ", excp); // $NON-NLS-1$ + } + + clusterInfo.setLifeTimeLimit(oldLifeTimeLimit); + clusterInfo.setClusterRecyclingKillProblemProcesses(oldRecyclingKillProcesses); + clusterInfo.setExpirationTimeout(oldExpirationTimeout); + + if (!server.regCluster(clusterInfo)) { + Helper.showMessageBox("Error returning cluster properties"); + } + }); + + thread.start(); + } + }; + + SelectionAdapter applyAssignmentRuleListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + TreeItem[] item = serversTree.getSelection(); + if (item.length == 0) { + return; + } + + Server server = getServer(item[0]); + UUID clusterId = getClusterId(item[0]); + + if (server == null || clusterId == null) { + return; + } + + Object data = ((MenuItem) event.widget).getData(); + if (data instanceof Integer) { + server.applyAssignmentRules(clusterId, (int) data); + } + } + }; + SelectionAdapter createInfobaseListener = // TODO вызывается из контекстного меню и из тулбара // нет ли ошибки serversTree.getSelection() при вызове из тулбара @@ -2282,6 +3228,27 @@ public void widgetSelected(SelectionEvent event) { } }; + SelectionAdapter launchV8ActionListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + TreeItem[] items = serversTree.getSelection(); + if (items.length == 0) { + return; + } + + TreeItem infobaseItem = items[0]; + BackgroundTask backgroundTask = + new BackgroundTask((V8ActionVariant) event.widget.getData()); + + Map params = fillParams(backgroundTask, infobaseItem); + if (!params.isEmpty()) { + backgroundTask.setParams(params); + addToTasksQueue(backgroundTask); + } + } + }; + SelectionAdapter createWorkingServerListener = new SelectionAdapter() { @Override @@ -2404,8 +3371,7 @@ public void handleEvent(Event e) { TableColumn column = (TableColumn) e.widget; Table currentTable = column.getParent(); - final Class clazz = - linksTablesToExtendedClass.get(currentTab); + final Class clazz = (Class) currentTable.getData(); if (clazz != null) { config.setColumnsOrder(clazz, currentTable.getColumnOrder()); } @@ -2420,13 +3386,15 @@ public void handleEvent(Event e) { public void handleEvent(Event e) { TableColumn column = (TableColumn) e.widget; - int newWidth = column.getWidth(); Table currentTable = column.getParent(); + + int newWidth = column.getWidth(); TableColumn[] columns = currentTable.getColumns(); + final Class clazz = (Class) currentTable.getData(); for (int i = 0; i < columns.length; i++) { if (columns[i].getText().equals(column.getText())) { - config.setColumnsWidth(linksTablesToExtendedClass.get(currentTab), i, newWidth); + config.setColumnsWidth(clazz, i, newWidth); break; } } @@ -2437,17 +3405,16 @@ public void handleEvent(Event e) { Listener columnSortListener = new Listener() { public void handleEvent(Event e) { - Table currentTable = getCurrentTable(); - if (currentTable == null) { - return; - } + TableColumn column = (TableColumn) e.widget; + Table currentTable = column.getParent(); + + int numColumn = (int) column.getData(); - ColumnProperties columnProperties = getColumnProperties(currentTab); + final Class clazz = (Class) currentTable.getData(); + ColumnProperties columnProperties = getColumnProperties(clazz); if (columnProperties == null) { return; } - TableColumn column = (TableColumn) e.widget; - int numColumn = (int) column.getData(); columnProperties.setSortColumn(numColumn); currentTable.setSortColumn(column); @@ -2456,152 +3423,72 @@ public void handleEvent(Event e) { // сортировка того что уже есть в списке TableItem[] items = currentTable.getItems(); - for (int i = 1; i < items.length; i++) { - BaseInfoExtended secondString = (BaseInfoExtended) items[i].getData(EXTENDED_INFO); + if (clazz == IAssignmentRuleInfo.class) { + tnfTableViewer.refresh(); + } + if (clazz != IAssignmentRuleInfo.class) { + for (int i = 1; i < items.length; i++) { + BaseInfoExtended secondString = (BaseInfoExtended) items[i].getData(EXTENDED_INFO); - for (int j = 0; j < i; j++) { - BaseInfoExtended firstString = (BaseInfoExtended) items[j].getData(EXTENDED_INFO); + for (int j = 0; j < i; j++) { + BaseInfoExtended firstString = (BaseInfoExtended) items[j].getData(EXTENDED_INFO); - if (firstString.compareTo(secondString) > 0) { - items[i].dispose(); - secondString.addToTable(currentTable, j); - items = currentTable.getItems(); - break; + if (firstString.compareTo(secondString) > 0) { + items[i].dispose(); + secondString.addToTable(currentTable, j); + items = currentTable.getItems(); + break; + } } } } } }; - SelectionAdapter updateTablesListener = - new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - fillTabs(); - } - }; - - SelectionAdapter editItemInTablesListener = + // SelectionAdapter updateTablesListener = + // new SelectionAdapter() { + // @Override + // public void widgetSelected(SelectionEvent e) { + // if (e.detail == SWT.ARROW) { + // ToolItem item = (ToolItem) e.widget; + // Rectangle rect = item.getBounds(); + // Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y)); + // menu.setLocation(pt.x, pt.y + rect.height); + // menu.setVisible(true); + // } else { + // System.out.println(dropdown.getText() + " Pressed"); + // fillTabs(); + // } + // } + // }; + + SelectionAdapter copyCellValueInTablesListener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - TableItem[] item = getCurrentTable().getSelection(); - if (item.length == 0) { - return; - } - - if (currentTab.equals(tabSessions)) { - - SessionInfoExtended sessionExtInfo = - (SessionInfoExtended) item[0].getData(EXTENDED_INFO); - - SessionInfoDialog dialog; - try { - dialog = - new SessionInfoDialog(getParent().getDisplay().getActiveShell(), sessionExtInfo); - } catch (Exception excp) { - excp.printStackTrace(); - LOGGER.error( - "Error init SessionInfoDialog for session id {}", //$NON-NLS-1$ - sessionExtInfo.getSessionInfo().getSid(), - excp); - return; - } - - dialog.open(); - - } else if (currentTab.equals(tabWorkingServers)) { - - WorkingServerInfoExtended workingServerExtInfo = - (WorkingServerInfoExtended) item[0].getData(EXTENDED_INFO); - - WorkingServerDialog dialog; - try { - dialog = - new WorkingServerDialog( - getParent().getDisplay().getActiveShell(), workingServerExtInfo); - } catch (Exception excp) { - excp.printStackTrace(); - LOGGER.error( - "Error init WorkingServerDialog for cluster id {}", //$NON-NLS-1$ - workingServerExtInfo.getWorkingServerId(), - excp); - return; - } - - int dialogResult = dialog.open(); - if (dialogResult == 0) { - // clickItemInServerTree(0); // TODO что здесь должно делаться??? - fillTabs(); - } - } else { - return; + TableItem[] selection = getCurrentTable().getSelection(); + if (selection.length > 0) { + Clipboard clipboard = new Clipboard(Display.getDefault()); + clipboard.setContents( + new Object[] {selection[0].getText(lastSelectColumn)}, + new Transfer[] {TextTransfer.getInstance()}); + clipboard.dispose(); } } }; - SelectionAdapter deleteItemInTablesListener = + SelectionAdapter switchWatchingMenuListener = new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - TableItem[] selectedItems = getCurrentTable().getSelection(); - if (selectedItems.length == 0) { - return; - } - - for (TableItem item : selectedItems) { - item.setForeground(deletedItemColor); // TODO успевает ли окраситься в красный цвет - - // BaseInfoExtended extInfo = (BaseInfoExtended) item.getData("ExtendedInfo"); - // //$NON-NLS-1$ - // Server server = extInfo.getServer(); - // UUID clusterId = extInfo.getClusterId(); - - if (currentTab.equals(tabSessions)) { - SessionInfoExtended extInfo = (SessionInfoExtended) item.getData(EXTENDED_INFO); - - Server server = extInfo.getServer(); - UUID clusterId = extInfo.getClusterId(); - UUID sessionId = extInfo.getSessionInfo().getSid(); - - if (server.terminateSession(clusterId, sessionId)) { - item.dispose(); - } - - } else if (currentTab.equals(tabConnections)) { - ConnectionInfoExtended extInfo = (ConnectionInfoExtended) item.getData(EXTENDED_INFO); - - Server server = extInfo.getServer(); - UUID clusterId = extInfo.getClusterId(); - UUID pricessId = extInfo.getConnectionInfo().getWorkingProcessId(); - UUID connectionId = extInfo.getConnectionInfo().getInfoBaseConnectionId(); - UUID infobaseId = extInfo.getConnectionInfo().getInfoBaseId(); - - if (server.disconnectConnection(clusterId, pricessId, connectionId, infobaseId)) { - item.dispose(); // update tableConnections - } - - } else if (currentTab.equals(tabWorkingServers)) { - WorkingServerInfoExtended extInfo = - (WorkingServerInfoExtended) item.getData(EXTENDED_INFO); - - Server server = extInfo.getServer(); - UUID clusterId = extInfo.getClusterId(); - UUID workingServerId = extInfo.getWorkingServerId(); - - int answer = - Helper.showQuestionBox( - Messages.getString("ViewerArea.DeleteServerQuestion")); //$NON-NLS-1$ - - if (answer == SWT.YES && server.unregWorkingServer(clusterId, workingServerId)) { - item.dispose(); // update tableWorkingServers - } - - } else { - break; - } + TableItem[] selection = getCurrentTable().getSelection(); + if (selection.length > 0) { + TableItem item = selection[0]; + item.setChecked(!item.getChecked()); + SessionInfoExtended ext = (SessionInfoExtended) item.getData(EXTENDED_INFO); + ext.switchWatching(item, item.getChecked()); } } }; @@ -2618,7 +3505,7 @@ public void handleEvent(Event event) { } }; - Listener mouseSelectCellListener = + Listener mouseSelectCellListener = // TODO не используется? new Listener() { @Override public void handleEvent(Event event) { @@ -2649,34 +3536,51 @@ public void handleEvent(Event event) { new MouseAdapter() { @Override public void mouseDown(MouseEvent event) { - if (event.button != 1) { + if (event.button != 1 && event.button != 3) { return; } - Table currentTable = (Table) event.widget; + currentTable = (Table) event.widget; Point pt = new Point(event.x, event.y); TableItem item = currentTable.getItem(pt); - if (item != null) { - for (int col = 0; col < currentTable.getColumnCount(); col++) { - Rectangle rect = item.getBounds(col); - if (rect.contains(pt)) { - if (lastSelectItem != null && !lastSelectItem.isDisposed()) { - lastSelectItem.setForeground(lastSelectColumn, null); - } - item.setForeground(col, Helper.getOrangeColor()); + if (item == null) { + currentTable.deselectAll(); + return; + } - lastSelectItem = item; - lastSelectColumn = col; - break; + for (int col = 0; col < currentTable.getColumnCount(); col++) { + Rectangle rect = item.getBounds(col); + if (rect.contains(pt)) { + + if (lastSelectItem != null && !lastSelectItem.isDisposed()) { + lastSelectItem.setForeground(lastSelectColumn, null); } + item.setForeground(col, Helper.getOrangeColor()); + + // заполнение таблицы с ТНФ + if (currentTable.equals(tableWorkingServers) && !item.equals(lastSelectItem)) { + WorkingServerInfoExtended ws = + (WorkingServerInfoExtended) item.getData(EXTENDED_INFO); + fillAssignmentRulesTable(ws); + } + + lastSelectItem = item; + lastSelectColumn = col; + break; } } } @Override - public void mouseDoubleClick(MouseEvent e) { - editItemInTablesListener.widgetSelected(null); + public void mouseDoubleClick(MouseEvent event) { + currentTable = (Table) event.widget; + TableItem[] item = currentTable.getSelection(); + if (item.length == 0) { + return; + } + editItemInTable(item[0]); + } }; @@ -2686,31 +3590,35 @@ public void mouseDoubleClick(MouseEvent e) { public void keyPressed(KeyEvent e) { final int keyC = 99; + currentTable = (Table) e.widget; + TableItem[] items = currentTable.getSelection(); switch (e.keyCode) { - case SWT.F2: - editItemInTablesListener.widgetSelected(null); + case SWT.F5: + refreshCurrentList(); break; - case SWT.F5: - fillTabs(); + case SWT.INSERT: + addItemInTable(currentTable); + break; + + case SWT.F2: + if (items.length == 0) { + return; + } + editItemInTable(items[0]); break; case SWT.DEL: - deleteItemInTablesListener.widgetSelected(null); + if (items.length == 0) { + return; + } + deleteItemsFromTable(items); break; case keyC: if (e.stateMask == SWT.CTRL) { - TableItem[] selection = getCurrentTable().getSelection(); - - if (selection.length > 0) { - Clipboard clipboard = new Clipboard(Display.getDefault()); - clipboard.setContents( - new Object[] {selection[0].getText(lastSelectColumn)}, - new Transfer[] {TextTransfer.getInstance()}); - clipboard.dispose(); - } + copyCellValueInTablesListener.widgetSelected(null); } break; @@ -2720,6 +3628,304 @@ public void keyPressed(KeyEvent e) { } }; + MouseAdapter tableTaskMouseClickListener = + new MouseAdapter() { + @Override + public void mouseDown(MouseEvent event) { + if (event.button != 1) { + return; + } + TableItem[] tableItem = tableTasks.getSelection(); + if (tableItem.length == 0) { + return; + } + + BackgroundTask task = (BackgroundTask) tableItem[0].getData(); + + tableItem[0].setText(task.getDescription()); + + tableTaskLog.setText(task.getLog()); + } + + @Override + public void mouseDoubleClick(MouseEvent e) { + // editItemInTablesListener.widgetSelected(null); + } + }; + + private class ServerConnectionCheckerTimer extends TimerTask { + + @Override + public void run() { + + Display.getDefault() + .asyncExec( + new Runnable() { + public void run() { + if (serverConnectionTimer == null) { + return; + } + + List doneItems = new ArrayList<>(); + + for (TreeItem serverItem : waitingConnectServers) { + Server server = getServer(serverItem); + if (server == null) { + return; + } + server.updateTreeItemState(serverItem); + + if (server.isConnected() || !server.getConnectionError().isBlank()) { + doneItems.add(serverItem); + } + } + + waitingConnectServers.removeAll(doneItems); + if (waitingConnectServers.isEmpty()) { + serverConnectionTimer.cancel(); + serverConnectionTimer = null; + } + + for (TreeItem serverItem : doneItems) { + Server server = getServer(serverItem); + if (server == null) { + return; + } + // server.updateTreeItemState(serverItem); + + if (server.isConnected()) { + updateClustersInTree(serverItem); + } + if (server.needShowConnectionError()) { + Helper.showMessageBox(server.getConnectionError()); + } + } + } + }); + } + } + + private class UpdateListTimer extends TimerTask { + + @Override + public void run() { + // fillTabs(); + + Display.getDefault() + .asyncExec( + new Runnable() { + public void run() { + refreshCurrentList(); + } + }); + } + } + + class TaskChekerTimer extends TimerTask { + + @Override + public void run() { + + Display.getDefault() + .asyncExec( + new Runnable() { + public void run() { + TableItem[] items = tableTasks.getItems(); + TableItem[] selectItems = tableTasks.getSelection(); + + BackgroundTask.resetCount(); + + for (TableItem tableItem : items) { + BackgroundTask task = (BackgroundTask) tableItem.getData(); + task.update(tableItem); + + if (selectItems.length > 0 + && tableItem.equals(selectItems[0]) + && (task.isRunning() + || tableTaskLog.getLineCount() != task.getLog().lines().count())) { + tableTaskLog.setText(task.getLog()); + } + } + + BackgroundTask.setTabTitle(tabTask); + + if (BackgroundTask.getRunningCount() == 0) { + taskTimer.cancel(); + taskTimer = null; + } + } + }); + } + } + + class UserScriptRunner extends SelectionAdapter { + + // поля + // private Menu menuUserScripts; + + public UserScriptRunner(Menu parentMenu) { + // this.menuUserScripts = parentMenu; + + addMenuSeparator(parentMenu); + Menu menuUserScripts = addItemGroupInMenu(parentMenu, "Пользовательские скрипты", null); + this.fillUserScriptsItems(menuUserScripts); + } + + public void fillUserScriptsItems(Menu subMenuUserScripts) { + Arrays.stream(subMenuUserScripts.getItems()).forEach(Widget::dispose); + // filter на элемент "Обновить" ??? + + addItemInMenu(subMenuUserScripts, Strings.CONTEXT_MENU_UPDATE, updateIcon16, this, null); + addMenuSeparator(subMenuUserScripts); + + // чтение каталога скриптов и создание подэлементов + readUserScripts() + .forEach( + script -> addItemInMenu(subMenuUserScripts, script.getName(), null, this, script)); + } + + private List readUserScripts() { + if (!config.isWindows()) { + return new ArrayList<>(); + } + + File userScriptsDir = new File("scripts"); // $NON-NLS-1$ + if (!userScriptsDir.exists()) { + userScriptsDir.mkdir(); + // можно скачивать скрипты с репозитория + } + // userScripts.clear(); + List userScripts = new ArrayList<>(); + if (userScriptsDir.exists() && userScriptsDir.isDirectory()) { + File[] scripts = userScriptsDir.listFiles(); + for (File script : scripts) { + if (script.isFile()) { + userScripts.add(script); + } + } + } + return userScripts; + } + + @Override + public void widgetSelected(SelectionEvent event) { + TreeItem[] items = serversTree.getSelection(); + if (items.length == 0) { + return; + } + + Object scriptData = event.widget.getData(); + if (scriptData == null) { + Menu subMenuUserScripts = ((MenuItem) event.widget).getParent(); + fillUserScriptsItems(subMenuUserScripts); + return; + } + + TreeItem infobaseItem = items[0]; + File script = (File) scriptData; + + BackgroundTask backgroundTask = new BackgroundTask(script); + Map params = fillParams(backgroundTask, infobaseItem); + if (!params.isEmpty()) { + backgroundTask.setParams(params); + addToTasksQueue(backgroundTask); + } + } + } + + class RefreshTablesSelectionListener implements Listener { + + private ToolItem mainButton; + private Menu dropdownMenu; + private int refreshRate = config.getListRrefreshRate(); + + public RefreshTablesSelectionListener(ToolItem mainButton) { + this.mainButton = mainButton; + this.mainButton.addListener(SWT.Selection, this); + + dropdownMenu = new Menu(mainButton.getParent().getShell()); + + this.add(dropdownMenu, "Автообновление", SWT.CHECK, null); + + // this.add(dropdownMenu, "Задать период автообновления", SWT.PUSH); + Menu subMenuUpdatePeriod = addItemGroupInMenu(dropdownMenu, "Период", null); + // подменю с секундами = 1, 2, 5, 10 + this.add(subMenuUpdatePeriod, "1 сек", SWT.RADIO, 1000); + this.add(subMenuUpdatePeriod, "2 сек", SWT.RADIO, 2000); + this.add(subMenuUpdatePeriod, "5 сек", SWT.RADIO, 5000); + this.add(subMenuUpdatePeriod, "10 сек", SWT.RADIO, 10000); + } + + public void add(Menu parentMenu, String title, int style, Object data) { + MenuItem menuItem = new MenuItem(parentMenu, style); + menuItem.setText(title); + menuItem.setData(data); + if (style == SWT.CHECK) { + menuItem.setImage(updateAutoIcon24); + menuItem.addSelectionListener(checkItemListener); + } + if (style == SWT.RADIO) { + menuItem.setSelection((int) data == refreshRate); + menuItem.addSelectionListener(radioItemListener); + } + } + + SelectionAdapter checkItemListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + MenuItem selected = (MenuItem) event.widget; + + if (selected.getStyle() != SWT.CHECK) { + return; + } + if (selected.getSelection()) { + updateListTimer = new Timer(true); + updateListTimer.schedule(new UpdateListTimer(), 1000, refreshRate); + mainButton.setImage(updateAutoIcon24); + } else { + updateListTimer.cancel(); + updateListTimer = null; + mainButton.setImage(updateIcon24); + } + } + }; + + SelectionAdapter radioItemListener = + new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + MenuItem selected = (MenuItem) event.widget; + + if (selected.getStyle() != SWT.RADIO) { + return; + } + if (selected.getSelection()) { + refreshRate = (int) selected.getData(); + config.setListRrefreshRate(refreshRate); + if (updateListTimer != null) { + updateListTimer.cancel(); + updateListTimer = new Timer(true); + updateListTimer.schedule(new UpdateListTimer(), 1000, refreshRate); + } + } + } + }; + + @Override + public void handleEvent(Event event) { + if (event.detail == SWT.ARROW) { + ToolItem item = (ToolItem) event.widget; + Rectangle rect = item.getBounds(); + Point pt = item.getParent().toDisplay(new Point(rect.x, rect.y)); + dropdownMenu.setLocation(pt.x, pt.y + rect.height); + dropdownMenu.setVisible(true); + } else { + refreshCurrentList(); + } + } + } + private static class Strings { static final String MENU_SERVERS = getString("MainMenu.Servers"); @@ -2729,6 +3935,7 @@ private static class Strings { static final String MENU_SERVICE = getString("MainMenu.Service"); static final String MENU_OPEN_SETTINGS = getString("MainMenu.OpenSettings"); static final String MENU_ABOUT = getString("MainMenu.About"); + static final String MENU_DONATE = getString("MainMenu.Donate"); static final String COLUMN_SERVER = getString("ColumnServer"); static final String TREE_INFOBASES_COUNT = getString("InfobasesCount"); @@ -2740,19 +3947,30 @@ private static class Strings { getString("ContextMenu.DisconnectOfServer"); static final String CONTEXT_MENU_SHOW_CONNECTION_ERROR = getString("ContextMenu.ShowConnectionError"); - static final String CONTEXT_MENU_CREATE = getString("ContextMenu.Create"); + + static final String CONTEXT_MENU_ADD = getString("ContextMenu.Add"); static final String CONTEXT_MENU_EDIT = getString("ContextMenu.Edit"); static final String CONTEXT_MENU_DELETE = getString("ContextMenu.Delete"); - static final String CONTEXT_MENU_ADD_SERVER = getString("ContextMenu.AddServer"); - static final String CONTEXT_MENU_EDIT_SERVER = getString("ContextMenu.EditServer"); + static final String CONTEXT_MENU_WATCH_SESSION = getString("ContextMenu.WatchSession"); + + static final String CONTEXT_MENU_ADD_HOTKEY = CONTEXT_MENU_ADD.concat("\tIns"); + static final String CONTEXT_MENU_EDIT_HOTKEY = CONTEXT_MENU_EDIT.concat("\tF2"); + static final String CONTEXT_MENU_DELETE_HOTKEY = CONTEXT_MENU_DELETE.concat("\tDEL"); + + static final String CONTEXT_MENU_COPY_CELL = + getString("ContextMenu.CopyCell").concat("\tCtrl+C"); + static final String CONTEXT_MENU_MOVE_UP = getString("ContextMenu.MoveUp"); static final String CONTEXT_MENU_MOVE_DOWN = getString("ContextMenu.MoveDown"); static final String CONTEXT_MENU_ORGANIZE_SERVERS = getString("ContextMenu.OrganizeServers"); - static final String CONTEXT_MENU_REMOVE_SERVER = getString("ContextMenu.RemoveServer"); static final String CONTEXT_MENU_CREATE_CLUSTER = getString("ContextMenu.CreateCluster"); static final String CONTEXT_MENU_EDIT_CLUSTER = getString("ContextMenu.EditCluster"); static final String CONTEXT_MENU_DELETE_CLUSTER = getString("ContextMenu.DeleteCluster"); + static final String CONTEXT_MENU_ADMINS = getString("ContextMenu.Admins"); + static final String CONTEXT_MENU_RESTART_PROCESSES = getString("ContextMenu.RestartProcesses"); + static final String CONTEXT_MENU_APPLY_PARTIAL_RULE = getString("ContextMenu.ApplyPartialRule"); + static final String CONTEXT_MENU_APPLY_FULL_RULE = getString("ContextMenu.ApplyFullRule"); static final String CONTEXT_MENU_CREATE_WORKING_SERVER = getString("ContextMenu.CreateWorkingServer"); @@ -2788,13 +4006,22 @@ private static class Strings { static final String CONTEXT_MENU_TERMINATE_USERS_SESSIONS = getString("ContextMenu.TerminateUsersSessions"); - static final String CONTEXT_MENU_VIEW_SESSION_F2 = - getString("ContextMenu.ViewSession").concat("\tF2"); + static final String CONTEXT_MENU_VIEW_HOTKEY = getString("ContextMenu.View").concat("\tF2"); static final String CONTEXT_MENU_KILL_SESSION_DEL = getString("ContextMenu.KillSession").concat("\tDEL"); static final String CONTEXT_MENU_KILL_CONNECTION_DEL = getString("ContextMenu.KillConnection").concat("\tDEL"); + static final String CONTEXT_MENU_INFOBASE_ACTIONS = getString("ContextMenu.InfobaseActions.Group"); + static final String CONTEXT_MENU_RUN_DESIGNER = getString("ContextMenu.InfobaseActions.RunDesigner"); + static final String CONTEXT_MENU_RUN_ENTERPRISE = getString("ContextMenu.InfobaseActions.RunEnterprise"); + static final String CONTEXT_MENU_DUMP_CF = getString("ContextMenu.InfobaseActions.DumpCf"); + static final String CONTEXT_MENU_LOAD_CF = getString("ContextMenu.InfobaseActions.LoadCf"); + static final String CONTEXT_MENU_DUMP_DT = getString("ContextMenu.InfobaseActions.DumpDt"); + static final String CONTEXT_MENU_LOAD_DT = getString("ContextMenu.InfobaseActions.LoadDt"); + + static final String ERROR_AUTH_FOR_RESTART_WP = getString("ErrorAuthForRestartWp"); + static String getString(String key) { return Messages.getString("ViewerArea." + key); //$NON-NLS-1$ } diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/WorkingServerDialog.java b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/WorkingServerDialog.java index f98e6e6..52b3431 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/WorkingServerDialog.java +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/WorkingServerDialog.java @@ -72,6 +72,7 @@ public class WorkingServerDialog extends Dialog { * @param server - server * @param clusterId - cluster ID * @param workingServerId - working server ID (null для создания нового) + * @wbp.parser.constructor */ public WorkingServerDialog( Shell parentShell, Server server, UUID clusterId, UUID workingServerId) { diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages.properties b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages.properties index 032c125..cedb735 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages.properties +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages.properties @@ -3,6 +3,7 @@ #Sun Apr 17 15:13:55 MSK 2022 AboutDialog.Autor = Autor:\r\nYanygin Sergey (Tula) +AboutDialog.Boosty_Description = Donate to the project on Boosty:\r\n%s AboutDialog.CurrentVersion = version %s AboutDialog.CurrentVersionIsLatest = (the latest version is installed) AboutDialog.CurrentVersionIsOld = (latest version is %s, download) @@ -14,6 +15,27 @@ AboutDialog.MainTitle = OneS Cluster Admin AboutDialog.Telegram_Description = Telegram:\r\n%s AboutDialog.TitleDialog = About +AdminDialog.AnswerDelete = Remove the administrator? +AdminDialog.Description = Description +AdminDialog.Name = Name +AdminDialog.Password = Password +AdminDialog.PasswordAuthAllowed = Pass auth. +AdminDialog.PasswordConfirm = Confirm +AdminDialog.PasswordsNotMatch = The entered passwords do not match +AdminDialog.SysAuthAllowed = OS auth. +AdminDialog.SysUsername = User +AdminDialog.TitleClusterEdit = Cluster administrator settings +AdminDialog.TitleClusterNew = New cluster administrator +AdminDialog.TitleList = Administrators +AdminDialog.TitleServerEdit = Main server administrator settings +AdminDialog.TitleServerNew = New main server administrator + +BackgroundTaskParams.FilterName = Files 1C (%s) +BackgroundTaskParams.ParamName = Param name +BackgroundTaskParams.ParamValue = Value +BackgroundTaskParams.Title = Set params for task: +BackgroundTaskParams.TitleFileDialog = Specify the location and file name + ClusterDialog.AcceptableDeviationOfTheNumberOfServerErrors = Acceptable deviation of the\r\nnumber of server errors (%) ClusterDialog.ClusterName = Cluster name ClusterDialog.ClusterRecyclingKillByMemoryWithDump = Cluster recycling kill by memory with dump @@ -60,8 +82,10 @@ InfobaseDialog.ExternalSessionManagement = External session management InfobaseDialog.InfobaseName = Name InfobaseDialog.LeaveDatabaseUnchanged = Leave the database and its contents unchanged InfobaseDialog.Locale = Locale +InfobaseDialog.PutSessionsDeniedMessage = Fill on the template InfobaseDialog.RequiredUseOfExternalManagement = Required use of external management InfobaseDialog.SafeModeSecurityProfile = Safe mode security profile +InfobaseDialog.SaveError = The parameters of the infobase are not saved - there are errors! InfobaseDialog.SecurityProfile = Security profile InfobaseDialog.ServerDBName = Server DB name InfobaseDialog.SessionsDenied = Sessions denied @@ -71,16 +95,20 @@ InfobaseDialog.SessionsDeniedParameter = Denied parameter InfobaseDialog.SessionsDeniedTo = Denied to (yyyy-mm-dd hh:mm:ss): InfobaseDialog.SessionsPermissionCode = Permission code InfobaseDialog.SheduledJobsDenied = Sheduled jobs denied +InfobaseDialog.SwitchDeniedEditingMode = Switch between the user-friendly and the regular version InfobaseDialog.TitleDialog = Infobase parameters InfobaseDialog.TitleDropInfobaseParameters = Delete infobase InfobaseDialog.YouNeedToEnter = you need to enter +NewServersDialog.TitleDialog = Selecting servers to add + ServerDialog.AgentParameters = Server agent parameters ServerDialog.AutoconnectAtStartup = Autoconnect to the server at startup ServerDialog.CentralServerAdminstrator = Central server adminstrator ServerDialog.ClusterName = Cluster name ServerDialog.ClustersCredentialsGroup = Clusters credentials ServerDialog.ConnectParameters = Connect parameters +ServerDialog.ConnectionVariant = Connection variant ServerDialog.Credentials = Credentials ServerDialog.Description = Description ServerDialog.Host = Host @@ -103,45 +131,57 @@ ServerDialog.UseRemoteRAS = Use remote RAS ServerDialog.Username = Username ServerDialog.V8Version = V8 version -SettingsDialog.CheckUpdate = Check update -SettingsDialog.ExpandClusters = Clusters -SettingsDialog.ExpandInfobases = Infobases -SettingsDialog.ExpandNodesInTree = Expand nodes in tree -SettingsDialog.ExpandServers = Servers -SettingsDialog.ExpandWorkingProcesses = Working processes -SettingsDialog.ExpandWorkingServers = Working servers -SettingsDialog.Highlight = Highlight -SettingsDialog.HighlightDuration = Highlight duration (sec) -SettingsDialog.HighlightNewItems = Highlight new items -SettingsDialog.Locale = Locale (need restart) -SettingsDialog.LocaleEnglish = English -SettingsDialog.LocaleRussian = Russian -SettingsDialog.LocaleSystem = System -SettingsDialog.ReadClipboard = Read clipboard (when adding server) -SettingsDialog.RowSortDirection = Row sort direction -SettingsDialog.RowSortDirectionAsPrevious = As previous -SettingsDialog.RowSortDirectionAscending = Descending -SettingsDialog.RowSortDirectionDescending = Ascending -SettingsDialog.ShadowSleepSessions = Shadow sleep sessions -SettingsDialog.ShowInfo = Additional info -SettingsDialog.ShowInfobaseDescription = Show infobase description -SettingsDialog.ShowLocalRASConnectInfo = About connecting via a local RAS -SettingsDialog.ShowNodesInTree = Show nodes in tree -SettingsDialog.ShowServerDescription = Show server description -SettingsDialog.ShowServerVersion = Show server version -SettingsDialog.ShowWorkingProcesses = Working processes -SettingsDialog.ShowWorkingServers = Working servers -SettingsDialog.TitleDialog = Parameters of the application -SettingsDialog.WatchSessions = Watch sessions color +SettingsDialog.CheckUpdate = Check update +SettingsDialog.ExpandClusters = Clusters +SettingsDialog.ExpandInfobases = Infobases +SettingsDialog.ExpandNodesInTree = Expand nodes in tree +SettingsDialog.ExpandServers = Servers +SettingsDialog.ExpandWorkingProcesses = Working processes +SettingsDialog.ExpandWorkingServers = Working servers +SettingsDialog.HighlightDuration = Highlight duration (sec) +SettingsDialog.HighlightNewItems = Highlight new items +SettingsDialog.HighlightTitle = Highlight +SettingsDialog.InfobaseDeniedEditMode = Infobase denied editing mode: +SettingsDialog.InfobaseDeniedFriendlyEditMode = User-friendly +SettingsDialog.InfobaseDeniedMessagePattern = Infobase denied message pattern:\r\n(start time - %1$s, end time - %2$s) +SettingsDialog.InfobaseDeniedStandardEditMode = Standard +SettingsDialog.IbasesFilePathTitle = The path to the "ibases.v8i" file: +SettingsDialog.LocaleEnglish = English +SettingsDialog.LocaleRussian = Russian +SettingsDialog.LocaleSystem = System +SettingsDialog.LocaleTitle = Locale (need restart) +SettingsDialog.LoggerLevelTitle = Logger level +SettingsDialog.ReadClipboard = Read clipboard (when adding server) +SettingsDialog.RequestLogon = Request a username when working with the infobase +SettingsDialog.RowSortDirectionAsPrevious = As previous +SettingsDialog.RowSortDirectionAscending = Descending +SettingsDialog.RowSortDirectionDescending = Ascending +SettingsDialog.RowSortDirectionTitle = Row sort direction +SettingsDialog.ShadowSleepSessions = Shadow sleep sessions +SettingsDialog.ShowCurrentDateAsTime = Show current date as time +SettingsDialog.ShowInfo = Additional info +SettingsDialog.ShowInfobaseDescription = Show infobase description +SettingsDialog.ShowLocalRASConnectInfo = About connecting via a local RAS +SettingsDialog.ShowNodesInTree = Show nodes in tree +SettingsDialog.ShowServerDescription = Show server description +SettingsDialog.ShowServerVersion = Show server version +SettingsDialog.ShowWorkingProcesses = Working processes +SettingsDialog.ShowWorkingServers = Working servers +SettingsDialog.TitleDialog = Parameters of the application +SettingsDialog.WatchSessions = Watch sessions color ViewerArea.Active = Active ViewerArea.ColumnServer = Server ViewerArea.ConnPerProcessLimit = Conn per process limit +ViewerArea.ContextMenu.Add = Add ViewerArea.ContextMenu.AddInFavorites = Add to favorites ViewerArea.ContextMenu.AddServer = Add server +ViewerArea.ContextMenu.Admins = Administrators +ViewerArea.ContextMenu.ApplyFullRule = Apply rule (full) +ViewerArea.ContextMenu.ApplyPartialRule = Apply rule (partial) ViewerArea.ContextMenu.ConnectToServer = Connect to server +ViewerArea.ContextMenu.CopyCell = Copy cell ViewerArea.ContextMenu.CopyInfobase = Copy infobase -ViewerArea.ContextMenu.Create = Create ViewerArea.ContextMenu.CreateCluster = Create cluster ViewerArea.ContextMenu.CreateInfobase = Create infobase ViewerArea.ContextMenu.CreateWorkingServer = Create working server @@ -156,6 +196,13 @@ ViewerArea.ContextMenu.EditCluster = Edit cluster ViewerArea.ContextMenu.EditInfobase = Edit infobase ViewerArea.ContextMenu.EditServer = Edit server ViewerArea.ContextMenu.EditWorkingServer = Edit working server +ViewerArea.ContextMenu.InfobaseActions.DumpCf = Dump CF +ViewerArea.ContextMenu.InfobaseActions.DumpDt = Dump DT +ViewerArea.ContextMenu.InfobaseActions.Group = Actions with the infobase +ViewerArea.ContextMenu.InfobaseActions.LoadCf = Load CF +ViewerArea.ContextMenu.InfobaseActions.LoadDt = Load DT +ViewerArea.ContextMenu.InfobaseActions.RunDesigner = Designer +ViewerArea.ContextMenu.InfobaseActions.RunEnterprise = Enterprise ViewerArea.ContextMenu.KillConnection = Kill connection ViewerArea.ContextMenu.KillSession = Kill session ViewerArea.ContextMenu.LockSessionsNow = Lock sessions now @@ -167,17 +214,21 @@ ViewerArea.ContextMenu.OrderInfobasesByFaforitesAndName = By favorites/name ViewerArea.ContextMenu.OrderInfobasesByName = By name ViewerArea.ContextMenu.OrganizeServers = Sort everything ViewerArea.ContextMenu.RemoveServer = Remove server +ViewerArea.ContextMenu.RestartProcesses = Restart working processes ViewerArea.ContextMenu.SessionManage = Session manage ViewerArea.ContextMenu.ShowConnectionError = Show connection error ViewerArea.ContextMenu.TerminateAllSessions = Terminate all sessions ViewerArea.ContextMenu.TerminateUsersSessions = Terminate users sessions ViewerArea.ContextMenu.Update = Update ViewerArea.ContextMenu.UpdateInfobases = Update infobases -ViewerArea.ContextMenu.ViewSession = Session info +ViewerArea.ContextMenu.View = View +ViewerArea.ContextMenu.WatchSession = Watch session ViewerArea.DedicatedManagers = Dedicated managers +ViewerArea.DeleteAssignmentRule = Do you really want to remove the assignment rule? ViewerArea.DeleteClusterQuestion = Deleting a cluster will delete its settings and the list of registered information databases. Do you really want to delete the cluster? ViewerArea.DeleteServerQuestion = Do you really want to remove the server from the list? ViewerArea.Description = Description +ViewerArea.ErrorAuthForRestartWp = To restart the working processes, you need to authenticate to the main server ViewerArea.IBPerProcessLimit = IB per process limit ViewerArea.IPPort = IP Port ViewerArea.IPPortMainManager = IP Port main manager @@ -185,6 +236,7 @@ ViewerArea.InfobasesCount = Infobases (%s) ViewerArea.MainMenu.About = About ViewerArea.MainMenu.ConnectAllServers = Connect to all servers ViewerArea.MainMenu.DisonnectAllServers = Disconnect from all servers +ViewerArea.MainMenu.Donate = Donate to the project ViewerArea.MainMenu.FindServers = Find Servers ViewerArea.MainMenu.OpenSettings = Settings ViewerArea.MainMenu.Servers = Servers diff --git a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages_ru_RU.properties b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages_ru_RU.properties index dd80728..e15ec6d 100644 --- a/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages_ru_RU.properties +++ b/clusterAdminLibrary/src/main/java/ru/yanygin/clusterAdminLibraryUI/messages_ru_RU.properties @@ -3,6 +3,7 @@ #Thu Sep 09 18:06:08 MSK 2021 AboutDialog.Autor = \u0410\u0432\u0442\u043E\u0440:\r\n\u042F\u043D\u044B\u0433\u0438\u043D \u0421\u0435\u0440\u0433\u0435\u0439 (\u0433. \u0422\u0443\u043B\u0430) +AboutDialog.Boosty_Description = \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442 \u043D\u0430 Boosty:\r\n%s AboutDialog.CurrentVersion = \u0432\u0435\u0440\u0441\u0438\u044F %s AboutDialog.CurrentVersionIsLatest = (\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0432\u0435\u0440\u0441\u0438\u044F) AboutDialog.CurrentVersionIsOld = (\u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0432\u0435\u0440\u0441\u0438\u044F %s, \u0441\u043A\u0430\u0447\u0430\u0442\u044C) @@ -14,6 +15,27 @@ AboutDialog.MainTitle = OneS Cluster Admin AboutDialog.Telegram_Description = Telegram:\r\n%s AboutDialog.TitleDialog = \u041E \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0435 +AdminDialog.AnswerDelete = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430? +AdminDialog.Description = \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 +AdminDialog.Name = \u0418\u043C\u044F +AdminDialog.Password = \u041F\u0430\u0440\u043E\u043B\u044C +AdminDialog.PasswordAuthAllowed = \u0410\u0443\u0442\u0435\u043D\u0442. \u043F\u0430\u0440\u043E\u043B\u0435\u043C +AdminDialog.PasswordConfirm = \u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043D\u0438\u0435 +AdminDialog.PasswordsNotMatch = \u0412\u0432\u0435\u0434\u0435\u043D\u043D\u044B\u0435 \u043F\u0430\u0440\u043E\u043B\u0438 \u043D\u0435 \u0441\u043E\u0432\u043F\u0430\u0434\u0430\u044E\u0442 +AdminDialog.SysAuthAllowed = \u0410\u0443\u0442\u0435\u043D\u0442. \u041E\u0421 +AdminDialog.SysUsername = \u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C +AdminDialog.TitleClusterEdit = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 +AdminDialog.TitleClusterNew = \u041D\u043E\u0432\u044B\u0439 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 +AdminDialog.TitleList = \u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u044B +AdminDialog.TitleServerEdit = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430 \u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +AdminDialog.TitleServerNew = \u041D\u043E\u0432\u044B\u0439 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440 \u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440\u0430 + +BackgroundTaskParams.FilterName = \u0424\u0430\u0439\u043B\u044B 1\u0421 (%s) +BackgroundTaskParams.ParamName = \u0418\u043C\u044F \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430 +BackgroundTaskParams.ParamValue = \u0417\u043D\u0430\u0447\u0435\u043D\u0438\u0435 +BackgroundTaskParams.Title = \u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043E\u0432 \u0434\u043B\u044F \u0437\u0430\u0434\u0430\u0447\u0438: +BackgroundTaskParams.TitleFileDialog = \u0423\u043A\u0430\u0436\u0438\u0442\u0435 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0438 \u0438\u043C\u044F \u0444\u0430\u0439\u043B\u0430 + ClusterDialog.AcceptableDeviationOfTheNumberOfServerErrors = \u0414\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u043E\u0435 \u043E\u0442\u043A\u043B\u043E\u043D\u0435\u043D\u0438\u0435 \u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\r\n\u043E\u0448\u0438\u0431\u043E\u043A \u0441\u0435\u0440\u0432\u0435\u0440\u0430 (%) ClusterDialog.ClusterName = \u0418\u043C\u044F \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 ClusterDialog.ClusterRecyclingKillByMemoryWithDump = \u0417\u0430\u043F\u0438\u0441\u044B\u0432\u0430\u0442\u044C \u0434\u0430\u043C\u043F \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \u043F\u0440\u0438 \u043F\u0440\u0435\u0432\u044B\u0448\u0435\u043D\u0438\u0438 \u043A\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043A\u043E\u0433\u043E \u043E\u0431\u044A\u0435\u043C\u0430 \u043F\u0430\u043C\u044F\u0442\u0438 @@ -60,8 +82,10 @@ InfobaseDialog.ExternalSessionManagement = \u0412\u043D\u0435\u0448\u043D\ InfobaseDialog.InfobaseName = \u0418\u043C\u044F InfobaseDialog.LeaveDatabaseUnchanged = \u041E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0431\u0430\u0437\u0443 \u0434\u0430\u043D\u043D\u044B\u0445 \u0438 \u0435\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u0431\u0435\u0437 \u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439 InfobaseDialog.Locale = \u042F\u0437\u044B\u043A (\u0421\u0442\u0440\u0430\u043D\u0430) +InfobaseDialog.PutSessionsDeniedMessage = \u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043F\u043E \u0448\u0430\u0431\u043B\u043E\u043D\u0443 InfobaseDialog.RequiredUseOfExternalManagement = \u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435 \u0432\u043D\u0435\u0448\u043D\u0435\u0433\u043E \u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F InfobaseDialog.SafeModeSecurityProfile = \u041F\u0440\u043E\u0444\u0438\u043B\u044C \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u0438\r\n\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0433\u043E \u0440\u0435\u0436\u0438\u043C\u0430 +InfobaseDialog.SaveError = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B \u043D\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u044B - \u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044F \u043E\u0448\u0438\u0431\u043A\u0438! InfobaseDialog.SecurityProfile = \u041F\u0440\u043E\u0444\u0438\u043B\u044C \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0441\u0442\u0438 InfobaseDialog.ServerDBName = \u0421\u0435\u0440\u0432\u0435\u0440 \u0431\u0430\u0437 \u0434\u0430\u043D\u043D\u044B\u0445 InfobaseDialog.SessionsDenied = \u0411\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u0435\u0430\u043D\u0441\u043E\u0432 \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0430 @@ -71,16 +95,20 @@ InfobaseDialog.SessionsDeniedParameter = \u041F\u0430\u0440\u0430\u043C\ InfobaseDialog.SessionsDeniedTo = \u041A\u043E\u043D\u0435\u0446 (yyyy-mm-dd hh:mm:ss): InfobaseDialog.SessionsPermissionCode = \u041A\u043E\u0434 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438\u044F InfobaseDialog.SheduledJobsDenied = \u0411\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0440\u0435\u0433\u043B\u0430\u043C\u0435\u043D\u0442\u043D\u044B\u0445 \u0437\u0430\u0434\u0430\u043D\u0438\u0439 \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0430 +InfobaseDialog.SwitchDeniedEditingMode = \u041F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442\u044C \u043C\u0435\u0436\u0434\u0443 \u0443\u043B\u0443\u0447\u0448\u0435\u043D\u043D\u044B\u043C \u0438 \u043E\u0431\u044B\u0447\u043D\u044B\u043C \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u043C InfobaseDialog.TitleDialog = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B InfobaseDialog.TitleDropInfobaseParameters = \u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B InfobaseDialog.YouNeedToEnter = \u043D\u0443\u0436\u043D\u043E \u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u044C +NewServersDialog.TitleDialog = \u0412\u044B\u0431\u043E\u0440 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0432 \u0434\u043B\u044F \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F + ServerDialog.AgentParameters = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u0430\u0433\u0435\u043D\u0442\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 ServerDialog.AutoconnectAtStartup = \u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0430\u0442\u044C\u0441\u044F \u043F\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 ServerDialog.CentralServerAdminstrator = \u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440 \u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440\u0430 ServerDialog.ClusterName = \u0418\u043C\u044F \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 ServerDialog.ClustersCredentialsGroup = \u0414\u0430\u043D\u043D\u044B\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\u0430 \u043A \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430\u043C ServerDialog.ConnectParameters = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F +ServerDialog.ConnectionVariant = \u0421\u043F\u043E\u0441\u043E\u0431 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F ServerDialog.Credentials = \u0414\u0430\u043D\u043D\u044B\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\u0430 ServerDialog.Description = \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 ServerDialog.Host = \u0425\u043E\u0441\u0442 @@ -103,45 +131,57 @@ ServerDialog.UseRemoteRAS = \u0418\u0441\u043F\u043E\u043B\u044C\ ServerDialog.Username = \u0418\u043C\u044F \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F ServerDialog.V8Version = \u0412\u0435\u0440\u0441\u0438\u044F V8 -SettingsDialog.CheckUpdate = \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F -SettingsDialog.ExpandClusters = \u041A\u043B\u0430\u0441\u0442\u0435\u0440\u044B -SettingsDialog.ExpandInfobases = \u0418\u043D\u0444\u043E\u0431\u0430\u0437\u044B -SettingsDialog.ExpandNodesInTree = \u0420\u0430\u0437\u0432\u043E\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044C \u0443\u0437\u043B\u044B \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 -SettingsDialog.ExpandServers = \u0421\u0435\u0440\u0432\u0435\u0440\u0430 -SettingsDialog.ExpandWorkingProcesses = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B -SettingsDialog.ExpandWorkingServers = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 -SettingsDialog.Highlight = \u041F\u043E\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u043D\u0438\u0435 -SettingsDialog.HighlightDuration = \u0414\u043B\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u043F\u043E\u0434\u0441\u0432\u0435\u0442\u043A\u0438 (\u0441\u0435\u043A) -SettingsDialog.HighlightNewItems = \u041F\u043E\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044C \u043D\u043E\u0432\u044B\u0435 \u0441\u0442\u0440\u043E\u043A\u0438 -SettingsDialog.Locale = \u042F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A) -SettingsDialog.LocaleEnglish = \u0410\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u0438\u0439 -SettingsDialog.LocaleRussian = \u0420\u0443\u0441\u0441\u043A\u0438\u0439 -SettingsDialog.LocaleSystem = \u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439 -SettingsDialog.ReadClipboard = \u0427\u0438\u0442\u0430\u0442\u044C \u0431\u0443\u0444\u0435\u0440 \u043E\u0431\u043C\u0435\u043D\u0430 (\u043F\u0440\u0438 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430) -SettingsDialog.RowSortDirection = \u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438 \u0441\u0442\u0440\u043E\u043A -SettingsDialog.RowSortDirectionAsPrevious = \u041A\u0430\u043A \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F -SettingsDialog.RowSortDirectionAscending = \u041F\u043E \u0443\u0431\u044B\u0432\u0430\u043D\u0438\u044E -SettingsDialog.RowSortDirectionDescending = \u041F\u043E \u0432\u043E\u0437\u0440\u0430\u0441\u0442\u0430\u043D\u0438\u044E -SettingsDialog.ShadowSleepSessions = \u0417\u0430\u0442\u0435\u043D\u044F\u0442\u044C \u0441\u043F\u044F\u0446\u0438\u0435 \u0441\u0435\u0430\u043D\u0441\u044B -SettingsDialog.ShowInfo = \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F -SettingsDialog.ShowInfobaseDescription = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B -SettingsDialog.ShowLocalRASConnectInfo = \u041E \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 RAS -SettingsDialog.ShowNodesInTree = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0443\u0437\u043B\u044B \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 -SettingsDialog.ShowServerDescription = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 -SettingsDialog.ShowServerVersion = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E \u0441\u0435\u0440\u0432\u0435\u0440\u0430 -SettingsDialog.ShowWorkingProcesses = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B -SettingsDialog.ShowWorkingServers = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 -SettingsDialog.TitleDialog = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F -SettingsDialog.WatchSessions = \u0426\u0432\u0435\u0442 \u043E\u0442\u0441\u043B\u0435\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 +SettingsDialog.CheckUpdate = \u041F\u0440\u043E\u0432\u0435\u0440\u044F\u0442\u044C \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F +SettingsDialog.ExpandClusters = \u041A\u043B\u0430\u0441\u0442\u0435\u0440\u044B +SettingsDialog.ExpandInfobases = \u0418\u043D\u0444\u043E\u0431\u0430\u0437\u044B +SettingsDialog.ExpandNodesInTree = \u0420\u0430\u0437\u0432\u043E\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044C \u0443\u0437\u043B\u044B \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 +SettingsDialog.ExpandServers = \u0421\u0435\u0440\u0432\u0435\u0440\u0430 +SettingsDialog.ExpandWorkingProcesses = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B +SettingsDialog.ExpandWorkingServers = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +SettingsDialog.HighlightDuration = \u0414\u043B\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C \u043F\u043E\u0434\u0441\u0432\u0435\u0442\u043A\u0438 (\u0441\u0435\u043A) +SettingsDialog.HighlightNewItems = \u041F\u043E\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044C \u043D\u043E\u0432\u044B\u0435 \u0441\u0442\u0440\u043E\u043A\u0438 +SettingsDialog.HighlightTitle = \u041F\u043E\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u043D\u0438\u0435 +SettingsDialog.InfobaseDeniedEditMode = \u0412\u0430\u0440\u0438\u0430\u043D\u0442 \u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0434\u0430\u0442\u044B \u0437\u0430\u043F\u0440\u0435\u0442\u0430 \u0432\u0445\u043E\u0434\u0430 \u0432 \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B: +SettingsDialog.InfobaseDeniedFriendlyEditMode = \u0423\u043B\u0443\u0447\u0448\u0435\u043D\u043D\u044B\u0439 +SettingsDialog.InfobaseDeniedMessagePattern = \u0428\u0430\u0431\u043B\u043E\u043D \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B:\r\n(\u0432\u0440\u0435\u043C\u044F \u043D\u0430\u0447\u0430\u043B\u0430 - %1$s, \u0432\u0440\u0435\u043C\u044F \u043E\u043A\u043E\u043D\u0447\u0430\u043D\u0438\u044F - %2$s) +SettingsDialog.InfobaseDeniedStandardEditMode = \u0421\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u044B\u0439 +SettingsDialog.IbasesFilePathTitle = \u041F\u0443\u0442\u044C \u043A \u0444\u0430\u0439\u043B\u0443 "ibases.v8i": +SettingsDialog.LocaleEnglish = \u0410\u043D\u0433\u043B\u0438\u0439\u0441\u043A\u0438\u0439 +SettingsDialog.LocaleRussian = \u0420\u0443\u0441\u0441\u043A\u0438\u0439 +SettingsDialog.LocaleSystem = \u0421\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0439 +SettingsDialog.LocaleTitle = \u042F\u0437\u044B\u043A \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 (\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044F \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A) +SettingsDialog.LoggerLevelTitle = \u0423\u0440\u043E\u0432\u0435\u043D\u044C \u043B\u043E\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F +SettingsDialog.ReadClipboard = \u0427\u0438\u0442\u0430\u0442\u044C \u0431\u0443\u0444\u0435\u0440 \u043E\u0431\u043C\u0435\u043D\u0430 (\u043F\u0440\u0438 \u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430) +SettingsDialog.RequestLogon = \u0417\u0430\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044C \u043B\u043E\u0433\u0438\u043D \u043F\u0440\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F\u0445 \u0441 \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u043E\u0439 +SettingsDialog.RowSortDirectionAsPrevious = \u041A\u0430\u043A \u043F\u0440\u0435\u0434\u044B\u0434\u0443\u0449\u0430\u044F +SettingsDialog.RowSortDirectionAscending = \u041F\u043E \u0443\u0431\u044B\u0432\u0430\u043D\u0438\u044E +SettingsDialog.RowSortDirectionDescending = \u041F\u043E \u0432\u043E\u0437\u0440\u0430\u0441\u0442\u0430\u043D\u0438\u044E +SettingsDialog.RowSortDirectionTitle = \u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438 \u0441\u0442\u0440\u043E\u043A +SettingsDialog.ShadowSleepSessions = \u0417\u0430\u0442\u0435\u043D\u044F\u0442\u044C \u0441\u043F\u044F\u0446\u0438\u0435 \u0441\u0435\u0430\u043D\u0441\u044B +SettingsDialog.ShowCurrentDateAsTime = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0432\u0440\u0435\u043C\u044F \u0432 \u0442\u0435\u043A\u0443\u0449\u0438\u0445 \u0434\u0430\u0442\u0430\u0445 +SettingsDialog.ShowInfo = \u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u0430\u044F \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F +SettingsDialog.ShowInfobaseDescription = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B +SettingsDialog.ShowLocalRASConnectInfo = \u041E \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0438 \u0447\u0435\u0440\u0435\u0437 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u044B\u0439 RAS +SettingsDialog.ShowNodesInTree = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0443\u0437\u043B\u044B \u0432 \u0434\u0435\u0440\u0435\u0432\u0435 +SettingsDialog.ShowServerDescription = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +SettingsDialog.ShowServerVersion = \u041F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u0432\u0435\u0440\u0441\u0438\u044E \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +SettingsDialog.ShowWorkingProcesses = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B +SettingsDialog.ShowWorkingServers = \u0420\u0430\u0431\u043E\u0447\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 +SettingsDialog.TitleDialog = \u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F +SettingsDialog.WatchSessions = \u0426\u0432\u0435\u0442 \u043E\u0442\u0441\u043B\u0435\u0436\u0438\u0432\u0430\u0435\u043C\u044B\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 ViewerArea.Active = \u0410\u043A\u0442\u0438\u0432\u043D\u044B\u0439 ViewerArea.ColumnServer = \u0421\u0435\u0440\u0432\u0435\u0440 ViewerArea.ConnPerProcessLimit = \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0439 \u043D\u0430 \u0440\u0430\u0431\u043E\u0447\u0438\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441 +ViewerArea.ContextMenu.Add = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C ViewerArea.ContextMenu.AddInFavorites = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0432 \u0438\u0437\u0431\u0440\u0430\u043D\u043D\u043E\u0435 ViewerArea.ContextMenu.AddServer = \u0414\u043E\u0431\u0430\u0432\u0438\u0442\u044C \u0441\u0435\u0440\u0432\u0435\u0440 +ViewerArea.ContextMenu.Admins = \u0410\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u044B +ViewerArea.ContextMenu.ApplyFullRule = \u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0422\u041D\u0424 (\u043F\u043E\u043B\u043D\u043E\u0435) +ViewerArea.ContextMenu.ApplyPartialRule = \u041F\u0440\u0438\u043C\u0435\u043D\u0438\u0442\u044C \u0422\u041D\u0424 (\u0447\u0430\u0441\u0442\u0438\u0447\u043D\u043E\u0435) ViewerArea.ContextMenu.ConnectToServer = \u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043A \u0441\u0435\u0440\u0432\u0435\u0440\u0443 +ViewerArea.ContextMenu.CopyCell = \u041A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u044F\u0447\u0435\u0439\u043A\u0443 ViewerArea.ContextMenu.CopyInfobase = \u0421\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u0443 -ViewerArea.ContextMenu.Create = \u0421\u043E\u0437\u0434\u0430\u0442\u044C ViewerArea.ContextMenu.CreateCluster = \u0421\u043E\u0437\u0434\u0430\u0442\u044C \u043A\u043B\u0430\u0441\u0442\u0435\u0440 ViewerArea.ContextMenu.CreateInfobase = \u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u0443 ViewerArea.ContextMenu.CreateWorkingServer = \u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0440\u0430\u0431\u043E\u0447\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 @@ -156,6 +196,13 @@ ViewerArea.ContextMenu.EditCluster = \u0420\u0435\u0434\u04 ViewerArea.ContextMenu.EditInfobase = \u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u0443 ViewerArea.ContextMenu.EditServer = \u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0435\u0440\u0432\u0435\u0440 ViewerArea.ContextMenu.EditWorkingServer = \u0420\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0440\u0430\u0431\u043E\u0447\u0438\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 +ViewerArea.ContextMenu.InfobaseActions.DumpCf = \u0412\u044B\u0433\u0440\u0443\u0437\u0438\u0442\u044C CF +ViewerArea.ContextMenu.InfobaseActions.DumpDt = \u0412\u044B\u0433\u0440\u0443\u0437\u0438\u0442\u044C DT +ViewerArea.ContextMenu.InfobaseActions.Group = \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044F \u0441 \u0431\u0430\u0437\u043E\u0439 +ViewerArea.ContextMenu.InfobaseActions.LoadCf = \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C CF +ViewerArea.ContextMenu.InfobaseActions.LoadDt = \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C DT +ViewerArea.ContextMenu.InfobaseActions.RunDesigner = \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0442\u043E\u0440 +ViewerArea.ContextMenu.InfobaseActions.RunEnterprise = \u041F\u0440\u0435\u0434\u043F\u0440\u0438\u044F\u0442\u0438\u0435 ViewerArea.ContextMenu.KillConnection = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 ViewerArea.ContextMenu.KillSession = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0435\u0430\u043D\u0441 ViewerArea.ContextMenu.LockSessionsNow = \u041D\u0435\u043C\u0435\u0434\u043B\u0435\u043D\u043D\u043E \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0441\u0435\u0430\u043D\u0441\u044B @@ -167,17 +214,21 @@ ViewerArea.ContextMenu.OrderInfobasesByFaforitesAndName = \u041F\u043E \u0438\u0 ViewerArea.ContextMenu.OrderInfobasesByName = \u041F\u043E \u0438\u043C\u0435\u043D\u0438 ViewerArea.ContextMenu.OrganizeServers = \u041E\u0442\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0432\u0441\u0435 ViewerArea.ContextMenu.RemoveServer = \u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0435\u0440\u0432\u0435\u0440 +ViewerArea.ContextMenu.RestartProcesses = \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0440\u0430\u0431\u043E\u0447\u0438\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B ViewerArea.ContextMenu.SessionManage = \u0423\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u0441\u0435\u0430\u043D\u0441\u0430\u043C\u0438 ViewerArea.ContextMenu.ShowConnectionError = \u041F\u043E\u043A\u0430\u0437\u0430\u0442\u044C \u043E\u0448\u0438\u0431\u043A\u0443 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F ViewerArea.ContextMenu.TerminateAllSessions = \u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044C \u0432\u0441\u0435 \u0441\u0435\u0430\u043D\u0441\u044B ViewerArea.ContextMenu.TerminateUsersSessions = \u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044C \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0435 \u0441\u0435\u0430\u043D\u0441\u044B ViewerArea.ContextMenu.Update = \u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C ViewerArea.ContextMenu.UpdateInfobases = \u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0438\u043D\u0444\u043E\u0431\u0430\u0437\u044B -ViewerArea.ContextMenu.ViewSession = \u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u043E \u0441\u0435\u0441\u0441\u0438\u0438 +ViewerArea.ContextMenu.View = \u041F\u0440\u043E\u0441\u043C\u043E\u0442\u0440 +ViewerArea.ContextMenu.WatchSession = \u0421\u043B\u0435\u0434\u0438\u0442\u044C \u0437\u0430 \u0441\u0435\u0430\u043D\u0441\u043E\u043C ViewerArea.DedicatedManagers = \u041C\u0435\u043D\u0435\u0434\u0436\u0435\u0440 \u043F\u043E\u0434 \u043A\u0430\u0436\u0434\u044B\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 +ViewerArea.DeleteAssignmentRule = \u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0440\u0430\u0432\u0438\u043B\u043E \u0422\u041D\u0424? ViewerArea.DeleteClusterQuestion = \u0423\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0430 \u043F\u0440\u0438\u0432\u0435\u0434\u0435\u0442 \u043A \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u044E \u0435\u0433\u043E \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u0438 \u0441\u043F\u0438\u0441\u043A\u0430 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0445 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u044B\u0445 \u0431\u0430\u0437. \u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043A\u043B\u0430\u0441\u0442\u0435\u0440? ViewerArea.DeleteServerQuestion = \u0412\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043B\u044C\u043D\u043E \u0445\u043E\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0441\u0435\u0440\u0432\u0435\u0440 \u0438\u0437 \u0441\u043F\u0438\u0441\u043A\u0430? ViewerArea.Description = \u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 +ViewerArea.ErrorAuthForRestartWp = \u0414\u043B\u044F \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u0440\u0430\u0431\u043E\u0447\u0438\u0445 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0432 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u044E \u043D\u0430 \u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u043E\u043C \u0441\u0435\u0440\u0432\u0435\u0440\u0435 ViewerArea.IBPerProcessLimit = \u041A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E \u0418\u0411 \u043D\u0430 \u043F\u0440\u043E\u0446\u0435\u0441\u0441 ViewerArea.IPPort = IP \u043F\u043E\u0440\u0442 ViewerArea.IPPortMainManager = IP \u043F\u043E\u0440\u0442 \u0446\u0435\u043D\u0442\u0440\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0441\u0435\u0440\u0432\u0435\u0440\u0430 @@ -185,6 +236,7 @@ ViewerArea.InfobasesCount = \u0418\u043D\u0444\u04 ViewerArea.MainMenu.About = \u041E \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0435 ViewerArea.MainMenu.ConnectAllServers = \u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043A\u043E \u0432\u0441\u0435\u043C \u0441\u0435\u0440\u0432\u0435\u0440\u0430\u043C ViewerArea.MainMenu.DisonnectAllServers = \u041E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043E\u0442 \u0432\u0441\u0435\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u0432 +ViewerArea.MainMenu.Donate = \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0430\u0442\u044C \u043F\u0440\u043E\u0435\u043A\u0442 ViewerArea.MainMenu.FindServers = \u041D\u0430\u0439\u0442\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 ViewerArea.MainMenu.OpenSettings = \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 ViewerArea.MainMenu.Servers = \u0421\u0435\u0440\u0432\u0435\u0440\u0430 diff --git a/clusterAdminLibrary/src/main/resources/icons/Rouble.png b/clusterAdminLibrary/src/main/resources/icons/Rouble.png new file mode 100644 index 0000000..39fb420 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/Rouble.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/add_24.png b/clusterAdminLibrary/src/main/resources/icons/add_24.png new file mode 100644 index 0000000..70d3829 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/add_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/connect_action_24.png b/clusterAdminLibrary/src/main/resources/icons/connect_action_24.png index 4dcd867..b968497 100644 Binary files a/clusterAdminLibrary/src/main/resources/icons/connect_action_24.png and b/clusterAdminLibrary/src/main/resources/icons/connect_action_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/delete_24.png b/clusterAdminLibrary/src/main/resources/icons/delete_24.png new file mode 100644 index 0000000..bf0e22a Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/delete_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/disconnect_action_24.png b/clusterAdminLibrary/src/main/resources/icons/disconnect_action_24.png index 6d28ffc..3d60423 100644 Binary files a/clusterAdminLibrary/src/main/resources/icons/disconnect_action_24.png and b/clusterAdminLibrary/src/main/resources/icons/disconnect_action_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/edit_24.png b/clusterAdminLibrary/src/main/resources/icons/edit_24.png new file mode 100644 index 0000000..ce67754 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/edit_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/server_disconnect_24.png b/clusterAdminLibrary/src/main/resources/icons/server_connectError_24.png similarity index 100% rename from clusterAdminLibrary/src/main/resources/icons/server_disconnect_24.png rename to clusterAdminLibrary/src/main/resources/icons/server_connectError_24.png diff --git a/clusterAdminLibrary/src/main/resources/icons/server_24.png b/clusterAdminLibrary/src/main/resources/icons/server_default_24.png similarity index 100% rename from clusterAdminLibrary/src/main/resources/icons/server_24.png rename to clusterAdminLibrary/src/main/resources/icons/server_default_24.png diff --git a/clusterAdminLibrary/src/main/resources/icons/taskCompleted.png b/clusterAdminLibrary/src/main/resources/icons/taskCompleted.png new file mode 100644 index 0000000..6925aed Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/taskCompleted.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/taskError.png b/clusterAdminLibrary/src/main/resources/icons/taskError.png new file mode 100644 index 0000000..4cb1a90 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/taskError.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/taskRunning.png b/clusterAdminLibrary/src/main/resources/icons/taskRunning.png new file mode 100644 index 0000000..2f2a072 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/taskRunning.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/tumblerOff.png b/clusterAdminLibrary/src/main/resources/icons/tumblerOff.png new file mode 100644 index 0000000..1def590 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/tumblerOff.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/tumblerOn.png b/clusterAdminLibrary/src/main/resources/icons/tumblerOn.png new file mode 100644 index 0000000..e7fb1e7 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/tumblerOn.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/updateAuto_24.png b/clusterAdminLibrary/src/main/resources/icons/updateAuto_24.png new file mode 100644 index 0000000..6b84947 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/updateAuto_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/update.png b/clusterAdminLibrary/src/main/resources/icons/update_16.png similarity index 100% rename from clusterAdminLibrary/src/main/resources/icons/update.png rename to clusterAdminLibrary/src/main/resources/icons/update_16.png diff --git a/clusterAdminLibrary/src/main/resources/icons/update_24.png b/clusterAdminLibrary/src/main/resources/icons/update_24.png new file mode 100644 index 0000000..6a28b79 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/update_24.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/view_16.png b/clusterAdminLibrary/src/main/resources/icons/view_16.png new file mode 100644 index 0000000..6bde4ee Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/view_16.png differ diff --git a/clusterAdminLibrary/src/main/resources/icons/watch.png b/clusterAdminLibrary/src/main/resources/icons/watch.png new file mode 100644 index 0000000..ec508f8 Binary files /dev/null and b/clusterAdminLibrary/src/main/resources/icons/watch.png differ diff --git a/clusterAdminLibrary/src/main/resources/logback.xml b/clusterAdminLibrary/src/main/resources/logback.xml index e9aa088..c8d3af0 100644 --- a/clusterAdminLibrary/src/main/resources/logback.xml +++ b/clusterAdminLibrary/src/main/resources/logback.xml @@ -23,16 +23,10 @@ - - - - - - - - + + \ No newline at end of file diff --git a/clusterAdminLibrary/src/test/java/ru/yanygin/clusterAdminLibrary/ConfigTest.java b/clusterAdminLibrary/src/test/java/ru/yanygin/clusterAdminLibrary/ConfigTest.java index d6682d3..f7cc1e9 100644 --- a/clusterAdminLibrary/src/test/java/ru/yanygin/clusterAdminLibrary/ConfigTest.java +++ b/clusterAdminLibrary/src/test/java/ru/yanygin/clusterAdminLibrary/ConfigTest.java @@ -73,9 +73,9 @@ void testCreateNewServer() { Server server = emptyConfig.createNewServer(); - assertEquals("Server", server.getAgentHost()); + assertEquals("Server1c", server.getAgentHost()); assertEquals("1540", server.getAgentPortAsString()); - assertEquals("Server", server.getRasHost()); + assertEquals("Server1c", server.getRasHost()); assertEquals("1545", server.getRasPortAsString()); } }