diff options
| author | Shireesh Anjal <anjalshireesh@gmail.com> | 2011-03-28 06:58:51 -0700 |
|---|---|---|
| committer | Shireesh Anjal <anjalshireesh@gmail.com> | 2011-03-28 06:58:51 -0700 |
| commit | bf531d097bc99db08bda4d1a1dec541c57c7933c (patch) | |
| tree | 253a3fc82d5bac3755fc7e32f8456879b69b9979 /src/com.gluster.storage.management.gui | |
| parent | b27c5d68d3ffa47c92e0fcd7d0873ac2d6b8fca8 (diff) | |
Preparing src for migration to github
Diffstat (limited to 'src/com.gluster.storage.management.gui')
170 files changed, 10794 insertions, 0 deletions
diff --git a/src/com.gluster.storage.management.gui/.classpath b/src/com.gluster.storage.management.gui/.classpath new file mode 100644 index 00000000..ad32c83a --- /dev/null +++ b/src/com.gluster.storage.management.gui/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> + <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> + <classpathentry kind="src" path="src"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/src/com.gluster.storage.management.gui/.project b/src/com.gluster.storage.management.gui/.project new file mode 100644 index 00000000..84ab78e4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/.project @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>com.gluster.storage.management.gui</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ManifestBuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.pde.SchemaBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.pde.PluginNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/src/com.gluster.storage.management.gui/.settings/org.eclipse.jdt.core.prefs b/src/com.gluster.storage.management.gui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 00000000..abf7cf5a --- /dev/null +++ b/src/com.gluster.storage.management.gui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Thu Nov 11 15:40:30 IST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF b/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF new file mode 100644 index 00000000..2e59c854 --- /dev/null +++ b/src/com.gluster.storage.management.gui/META-INF/MANIFEST.MF @@ -0,0 +1,27 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: glustersp-gui +Bundle-SymbolicName: com.gluster.storage.management.gui;singleton:=true +Bundle-Version: 1.0.0 +Bundle-Activator: com.gluster.storage.management.gui.Activator +Bundle-Vendor: Gluster +Require-Bundle: org.eclipse.ui;bundle-version="3.6.1", + org.eclipse.core.runtime;bundle-version="3.6.0", + org.eclipse.ui.forms;bundle-version="3.5.2", + org.eclipse.rcp;bundle-version="3.6.0", + com.gluster.storage.management.core;bundle-version="1.0.0", + com.gluster.storage.management.client;bundle-version="1.0.0", + org.eclipse.core.databinding;bundle-version="1.3.100", + org.eclipse.jface.databinding;bundle-version="1.4.0", + org.eclipse.core.databinding.property;bundle-version="1.3.0", + org.eclipse.core.databinding.beans;bundle-version="1.2.100", + org.eclipse.birt.chart.engine;bundle-version="2.6.1", + org.eclipse.birt.chart.engine.extension;bundle-version="2.6.1", + org.eclipse.birt.chart.device.extension;bundle-version="2.6.1", + org.eclipse.birt.chart.device.swt;bundle-version="2.6.1", + com.ibm.icu;bundle-version="4.2.1", + com.richclientgui.rcptoolbox;bundle-version="1.0.5", + org.eclipse.core.resources +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Bundle-ClassPath: . diff --git a/src/com.gluster.storage.management.gui/build.properties b/src/com.gluster.storage.management.gui/build.properties new file mode 100644 index 00000000..47ced62b --- /dev/null +++ b/src/com.gluster.storage.management.gui/build.properties @@ -0,0 +1,15 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + icons/,\ + product_lg.gif,\ + splash.bmp,\ + splash/,\ + images/,\ + plugin.xml,\ + preferences.ini +src.includes = icons/,\ + splash.bmp,\ + images/,\ + preferences.ini diff --git a/src/com.gluster.storage.management.gui/icons/arrow-down.png b/src/com.gluster.storage.management.gui/icons/arrow-down.png Binary files differnew file mode 100644 index 00000000..7f23e3f4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/arrow-down.png diff --git a/src/com.gluster.storage.management.gui/icons/arrow-up.png b/src/com.gluster.storage.management.gui/icons/arrow-up.png Binary files differnew file mode 100644 index 00000000..b8ad3050 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/arrow-up.png diff --git a/src/com.gluster.storage.management.gui/icons/cluster.png b/src/com.gluster.storage.management.gui/icons/cluster.png Binary files differnew file mode 100644 index 00000000..c9348a21 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/cluster.png diff --git a/src/com.gluster.storage.management.gui/icons/disk-migrate.png b/src/com.gluster.storage.management.gui/icons/disk-migrate.png Binary files differnew file mode 100644 index 00000000..2de348dc --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/disk-migrate.png diff --git a/src/com.gluster.storage.management.gui/icons/disk-uninitialized.png b/src/com.gluster.storage.management.gui/icons/disk-uninitialized.png Binary files differnew file mode 100644 index 00000000..b982d118 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/disk-uninitialized.png diff --git a/src/com.gluster.storage.management.gui/icons/disk.png b/src/com.gluster.storage.management.gui/icons/disk.png Binary files differnew file mode 100644 index 00000000..99d532e8 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/disk.png diff --git a/src/com.gluster.storage.management.gui/icons/disks.png b/src/com.gluster.storage.management.gui/icons/disks.png Binary files differnew file mode 100644 index 00000000..fc5a52f5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/disks.png diff --git a/src/com.gluster.storage.management.gui/icons/folder.png b/src/com.gluster.storage.management.gui/icons/folder.png Binary files differnew file mode 100644 index 00000000..784e8fa4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/folder.png diff --git a/src/com.gluster.storage.management.gui/icons/gluster_icon.png b/src/com.gluster.storage.management.gui/icons/gluster_icon.png Binary files differnew file mode 100644 index 00000000..f92e472d --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/gluster_icon.png diff --git a/src/com.gluster.storage.management.gui/icons/group.png b/src/com.gluster.storage.management.gui/icons/group.png Binary files differnew file mode 100644 index 00000000..7fb4e1f1 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/group.png diff --git a/src/com.gluster.storage.management.gui/icons/gsn.png b/src/com.gluster.storage.management.gui/icons/gsn.png Binary files differnew file mode 100644 index 00000000..68f21d30 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/gsn.png diff --git a/src/com.gluster.storage.management.gui/icons/logs.png b/src/com.gluster.storage.management.gui/icons/logs.png Binary files differnew file mode 100644 index 00000000..c8449f98 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/logs.png diff --git a/src/com.gluster.storage.management.gui/icons/mail.ico b/src/com.gluster.storage.management.gui/icons/mail.ico Binary files differnew file mode 100644 index 00000000..b0000611 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/mail.ico diff --git a/src/com.gluster.storage.management.gui/icons/minus-white.png b/src/com.gluster.storage.management.gui/icons/minus-white.png Binary files differnew file mode 100644 index 00000000..8efd5d33 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/minus-white.png diff --git a/src/com.gluster.storage.management.gui/icons/network-interface.png b/src/com.gluster.storage.management.gui/icons/network-interface.png Binary files differnew file mode 100644 index 00000000..24ca7370 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/network-interface.png diff --git a/src/com.gluster.storage.management.gui/icons/network-interfaces.png b/src/com.gluster.storage.management.gui/icons/network-interfaces.png Binary files differnew file mode 100644 index 00000000..752968bb --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/network-interfaces.png diff --git a/src/com.gluster.storage.management.gui/icons/network-interfaces1.png b/src/com.gluster.storage.management.gui/icons/network-interfaces1.png Binary files differnew file mode 100644 index 00000000..af438028 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/network-interfaces1.png diff --git a/src/com.gluster.storage.management.gui/icons/plus-white.png b/src/com.gluster.storage.management.gui/icons/plus-white.png Binary files differnew file mode 100644 index 00000000..c765946e --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/plus-white.png diff --git a/src/com.gluster.storage.management.gui/icons/preferences.png b/src/com.gluster.storage.management.gui/icons/preferences.png Binary files differnew file mode 100644 index 00000000..7b93eb05 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/preferences.png diff --git a/src/com.gluster.storage.management.gui/icons/progress-bar.png b/src/com.gluster.storage.management.gui/icons/progress-bar.png Binary files differnew file mode 100644 index 00000000..c7db00ae --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/progress-bar.png diff --git a/src/com.gluster.storage.management.gui/icons/question.png b/src/com.gluster.storage.management.gui/icons/question.png Binary files differnew file mode 100644 index 00000000..30a47032 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/question.png diff --git a/src/com.gluster.storage.management.gui/icons/sample.gif b/src/com.gluster.storage.management.gui/icons/sample.gif Binary files differnew file mode 100644 index 00000000..34fb3c9d --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/sample.gif diff --git a/src/com.gluster.storage.management.gui/icons/sample.icns b/src/com.gluster.storage.management.gui/icons/sample.icns Binary files differnew file mode 100644 index 00000000..1e92ccce --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/sample.icns diff --git a/src/com.gluster.storage.management.gui/icons/sample2.gif b/src/com.gluster.storage.management.gui/icons/sample2.gif Binary files differnew file mode 100644 index 00000000..252d7ebc --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/sample2.gif diff --git a/src/com.gluster.storage.management.gui/icons/sample3.gif b/src/com.gluster.storage.management.gui/icons/sample3.gif Binary files differnew file mode 100644 index 00000000..b949ac94 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/sample3.gif diff --git a/src/com.gluster.storage.management.gui/icons/search.png b/src/com.gluster.storage.management.gui/icons/search.png Binary files differnew file mode 100644 index 00000000..b4b23129 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/search.png diff --git a/src/com.gluster.storage.management.gui/icons/server-add-big.png b/src/com.gluster.storage.management.gui/icons/server-add-big.png Binary files differnew file mode 100644 index 00000000..d96b8175 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/server-add-big.png diff --git a/src/com.gluster.storage.management.gui/icons/server-add.png b/src/com.gluster.storage.management.gui/icons/server-add.png Binary files differnew file mode 100644 index 00000000..db604ee3 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/server-add.png diff --git a/src/com.gluster.storage.management.gui/icons/server-remove.png b/src/com.gluster.storage.management.gui/icons/server-remove.png Binary files differnew file mode 100644 index 00000000..5e9b2683 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/server-remove.png diff --git a/src/com.gluster.storage.management.gui/icons/server.png b/src/com.gluster.storage.management.gui/icons/server.png Binary files differnew file mode 100644 index 00000000..9bc37dce --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/server.png diff --git a/src/com.gluster.storage.management.gui/icons/servers.png b/src/com.gluster.storage.management.gui/icons/servers.png Binary files differnew file mode 100644 index 00000000..b18a74d9 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/servers.png diff --git a/src/com.gluster.storage.management.gui/icons/star-small.png b/src/com.gluster.storage.management.gui/icons/star-small.png Binary files differnew file mode 100644 index 00000000..fef14263 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/star-small.png diff --git a/src/com.gluster.storage.management.gui/icons/status-offline-circle.png b/src/com.gluster.storage.management.gui/icons/status-offline-circle.png Binary files differnew file mode 100644 index 00000000..20d6f5ea --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/status-offline-circle.png diff --git a/src/com.gluster.storage.management.gui/icons/status-offline-small.png b/src/com.gluster.storage.management.gui/icons/status-offline-small.png Binary files differnew file mode 100644 index 00000000..39d47690 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/status-offline-small.png diff --git a/src/com.gluster.storage.management.gui/icons/status-offline.png b/src/com.gluster.storage.management.gui/icons/status-offline.png Binary files differnew file mode 100644 index 00000000..6b9fa6dd --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/status-offline.png diff --git a/src/com.gluster.storage.management.gui/icons/status-online-circle.png b/src/com.gluster.storage.management.gui/icons/status-online-circle.png Binary files differnew file mode 100644 index 00000000..210b1a6c --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/status-online-circle.png diff --git a/src/com.gluster.storage.management.gui/icons/status-online-small.png b/src/com.gluster.storage.management.gui/icons/status-online-small.png Binary files differnew file mode 100644 index 00000000..8e87f2e5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/status-online-small.png diff --git a/src/com.gluster.storage.management.gui/icons/status-online.png b/src/com.gluster.storage.management.gui/icons/status-online.png Binary files differnew file mode 100644 index 00000000..2414885b --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/status-online.png diff --git a/src/com.gluster.storage.management.gui/icons/stop.png b/src/com.gluster.storage.management.gui/icons/stop.png Binary files differnew file mode 100644 index 00000000..0cfd5859 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/stop.png diff --git a/src/com.gluster.storage.management.gui/icons/ui-check-box-mix.png b/src/com.gluster.storage.management.gui/icons/ui-check-box-mix.png Binary files differnew file mode 100644 index 00000000..3c961711 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/ui-check-box-mix.png diff --git a/src/com.gluster.storage.management.gui/icons/ui-check-box-uncheck.png b/src/com.gluster.storage.management.gui/icons/ui-check-box-uncheck.png Binary files differnew file mode 100644 index 00000000..ba447358 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/ui-check-box-uncheck.png diff --git a/src/com.gluster.storage.management.gui/icons/ui-check-box.png b/src/com.gluster.storage.management.gui/icons/ui-check-box.png Binary files differnew file mode 100644 index 00000000..07f3522a --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/ui-check-box.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-create-big.png b/src/com.gluster.storage.management.gui/icons/volume-create-big.png Binary files differnew file mode 100644 index 00000000..231bae5b --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-create-big.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-create.png b/src/com.gluster.storage.management.gui/icons/volume-create.png Binary files differnew file mode 100644 index 00000000..9c8a9da4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-create.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-delete.png b/src/com.gluster.storage.management.gui/icons/volume-delete.png Binary files differnew file mode 100644 index 00000000..86f7fbc2 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-delete.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-edit.png b/src/com.gluster.storage.management.gui/icons/volume-edit.png Binary files differnew file mode 100644 index 00000000..291bfc76 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-edit.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-rebalance.png b/src/com.gluster.storage.management.gui/icons/volume-rebalance.png Binary files differnew file mode 100644 index 00000000..e213cd5b --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-rebalance.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-start.png b/src/com.gluster.storage.management.gui/icons/volume-start.png Binary files differnew file mode 100644 index 00000000..aace63ad --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-start.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-stop-1.png b/src/com.gluster.storage.management.gui/icons/volume-stop-1.png Binary files differnew file mode 100644 index 00000000..0cfd5859 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-stop-1.png diff --git a/src/com.gluster.storage.management.gui/icons/volume-stop.png b/src/com.gluster.storage.management.gui/icons/volume-stop.png Binary files differnew file mode 100644 index 00000000..7af3a518 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume-stop.png diff --git a/src/com.gluster.storage.management.gui/icons/volume.png b/src/com.gluster.storage.management.gui/icons/volume.png Binary files differnew file mode 100644 index 00000000..46b7564a --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume.png diff --git a/src/com.gluster.storage.management.gui/icons/volume1.png b/src/com.gluster.storage.management.gui/icons/volume1.png Binary files differnew file mode 100644 index 00000000..5e23dbc8 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volume1.png diff --git a/src/com.gluster.storage.management.gui/icons/volumes.png b/src/com.gluster.storage.management.gui/icons/volumes.png Binary files differnew file mode 100644 index 00000000..80dfa195 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volumes.png diff --git a/src/com.gluster.storage.management.gui/icons/volumes1.png b/src/com.gluster.storage.management.gui/icons/volumes1.png Binary files differnew file mode 100644 index 00000000..448e46fd --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volumes1.png diff --git a/src/com.gluster.storage.management.gui/icons/volumes2.png b/src/com.gluster.storage.management.gui/icons/volumes2.png Binary files differnew file mode 100644 index 00000000..0905f933 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volumes2.png diff --git a/src/com.gluster.storage.management.gui/icons/volumes3.png b/src/com.gluster.storage.management.gui/icons/volumes3.png Binary files differnew file mode 100644 index 00000000..7e90d397 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/volumes3.png diff --git a/src/com.gluster.storage.management.gui/icons/world.png b/src/com.gluster.storage.management.gui/icons/world.png Binary files differnew file mode 100644 index 00000000..68f21d30 --- /dev/null +++ b/src/com.gluster.storage.management.gui/icons/world.png diff --git a/src/com.gluster.storage.management.gui/images/gauge.png b/src/com.gluster.storage.management.gui/images/gauge.png Binary files differnew file mode 100644 index 00000000..6f5764ea --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/gauge.png diff --git a/src/com.gluster.storage.management.gui/images/gauge_small.png b/src/com.gluster.storage.management.gui/images/gauge_small.png Binary files differnew file mode 100644 index 00000000..71e424fe --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/gauge_small.png diff --git a/src/com.gluster.storage.management.gui/images/progress_image_empty.png b/src/com.gluster.storage.management.gui/images/progress_image_empty.png Binary files differnew file mode 100644 index 00000000..590097ad --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/progress_image_empty.png diff --git a/src/com.gluster.storage.management.gui/images/progress_image_filled_danger.png b/src/com.gluster.storage.management.gui/images/progress_image_filled_danger.png Binary files differnew file mode 100644 index 00000000..97704230 --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/progress_image_filled_danger.png diff --git a/src/com.gluster.storage.management.gui/images/progress_image_filled_safe.png b/src/com.gluster.storage.management.gui/images/progress_image_filled_safe.png Binary files differnew file mode 100644 index 00000000..ae4e3c69 --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/progress_image_filled_safe.png diff --git a/src/com.gluster.storage.management.gui/images/progress_image_left.png b/src/com.gluster.storage.management.gui/images/progress_image_left.png Binary files differnew file mode 100644 index 00000000..97704230 --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/progress_image_left.png diff --git a/src/com.gluster.storage.management.gui/images/progress_image_right.png b/src/com.gluster.storage.management.gui/images/progress_image_right.png Binary files differnew file mode 100644 index 00000000..97704230 --- /dev/null +++ b/src/com.gluster.storage.management.gui/images/progress_image_right.png diff --git a/src/com.gluster.storage.management.gui/plugin.xml b/src/com.gluster.storage.management.gui/plugin.xml new file mode 100644 index 00000000..f5ab3db7 --- /dev/null +++ b/src/com.gluster.storage.management.gui/plugin.xml @@ -0,0 +1,1175 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?eclipse version="3.4"?> +<plugin> + + <extension + id="application" + point="org.eclipse.core.runtime.applications"> + <application> + <run + class="com.gluster.storage.management.gui.Application"> + </run> + </application> + </extension> + <extension + point="org.eclipse.ui.perspectives"> + <perspective + name="Gluster Perspective" + class="com.gluster.storage.management.gui.Perspective" + id="com.gluster.storage.management.gui.perspective"> + </perspective> + </extension> + <extension + point="org.eclipse.ui.views"> + <view + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.NavigationView" + icon="icons/world.png" + id="com.gluster.storage.management.gui.views.NavigationView" + name="Cluster Navigation Tree" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.DetailsView" + icon="icons/gluster_icon.png" + id="com.gluster.storage.management.gui.views.details.DetailsView" + name="Details" + restorable="true"> + </view> + <view + category="org.eclipse.ui" + class="org.eclipse.ui.ExtensionFactory:progressView" + icon="icons/progress-bar.png" + id="org.eclipse.ui.views.ProgressView" + name="Tasks in Progress" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.DiscoveredServersView" + icon="icons/servers.png" + id="com.gluster.storage.management.gui.views.DiscoveredServersView" + name="Discovered Servers" + restorable="true"> + </view> + <view + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.DiscoveredServerView" + icon="icons/server.png" + id="com.gluster.storage.management.gui.views.DiscoveredServerView" + name="Discovered Server" + restorable="true"> + </view> + <category + id="com.gluster.storage.management.gui.category" + name="Gluster Managament Console"> + </category> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.VolumesView" + icon="icons/volumes.png" + id="com.gluster.storage.management.gui.views.VolumesView" + name="Volumes" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.VolumesSummaryView" + icon="icons/gluster_icon.png" + id="com.gluster.storage.management.gui.views.VolumesSummaryView" + name="Summary (Volumes)" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.ClusterSummaryView" + icon="icons/gluster_icon.png" + id="com.gluster.storage.management.gui.views.ClusterSummaryView" + name="Summary (Cluster)" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.VolumeSummaryView" + icon="icons/gluster_icon.png" + id="com.gluster.storage.management.gui.views.VolumeSummaryView" + name="Summary (Volume)" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.VolumeDisksView" + icon="icons/disks.png" + id="com.gluster.storage.management.gui.views.VolumeDisksView" + name="Disks (Volume)" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.VolumeOptionsView" + icon="icons/preferences.png" + id="com.gluster.storage.management.gui.views.VolumeOptionsView" + name="Volume Options" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.VolumeLogsView" + icon="icons/logs.png" + id="com.gluster.storage.management.gui.views.VolumeLogsView" + name="Volume Logs" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.GlusterServersSummaryView" + icon="icons/gluster_icon.png" + id="com.gluster.storage.management.gui.views.GlusterServersSummaryView" + name="Summary (Servers)" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.GlusterServersView" + icon="icons/servers.png" + id="com.gluster.storage.management.gui.views.GlusterServersView" + name="Servers" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.DisksView" + icon="icons/disks.png" + id="com.gluster.storage.management.gui.views.DisksView" + name="Disks" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.GlusterServerSummaryView" + icon="icons/gluster_icon.png" + id="com.gluster.storage.management.gui.views.GlusterServerSummaryView" + name="Summary (Server)" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.GlusterServerDisksView" + icon="icons/disks.png" + id="com.gluster.storage.management.gui.views.GlusterServerDisksView" + name="Server Disks" + restorable="true"> + </view> + <view + allowMultiple="false" + category="com.gluster.storage.management.gui.category" + class="com.gluster.storage.management.gui.views.GlusterServerLogsView" + icon="icons/logs.png" + id="com.gluster.storage.management.gui.views.GlusterServerLogsView" + name="Server Logs" + restorable="true"> + </view> + </extension> + <extension + point="org.eclipse.ui.commands"> + <category + name="Gluster Commands" + id="com.gluster.storage.management.gui.category"> + </category> + <command + name="Create Volume" + description="Create a new Volume" + categoryId="com.gluster.storage.management.gui.category" + id="com.gluster.storage.management.gui.commands.CreateVolume"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Delete Volume" + id="com.gluster.storage.management.gui.commands.DeleteVolume" + name="Delete Volume"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Start Volume" + id="com.gluster.storage.management.gui.commands.StartVolume" + name="Start Volume"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Stop Volume" + id="com.gluster.storage.management.gui.commands.StopVolume" + name="Stop Volume"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Edit Volume" + id="com.gluster.storage.management.gui.commands.EditVolume" + name="Edit Volume"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Rebalance Volume" + id="com.gluster.storage.management.gui.commands.RebalanceVolume" + name="Rebalance Volume"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Add Server(s) to Cluster" + id="com.gluster.storage.management.gui.commands.AddServer" + name="Add Server(s)"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Remove Server(s) from Cluster" + id="com.gluster.storage.management.gui.commands.RemoveServer" + name="Remove Server(s)"> + </command> + <command + categoryId="com.gluster.storage.management.gui.category" + description="Migrate Disk" + id="com.gluster.storage.management.gui.commands.MigrateDisk" + name="Migrate Disk"> + </command> + </extension> + <extension + point="org.eclipse.ui.bindings"> + <key + commandId="com.gluster.storage.management.gui.commands.CreateVolume" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+C"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.DeleteVolume" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+D"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.StartVolume" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+S"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.StopVolume" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+T"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.EditVolume" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+E"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.RebalanceVolume" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+B"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.AddServer" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+A"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.RemoveServer" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+R"> + </key> + <key + commandId="com.gluster.storage.management.gui.commands.MigrateDisk" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+M"> + </key> + <key + commandId="org.eclipse.ui.window.preferences" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+P"> + </key> + <key + commandId="org.eclipse.ui.window.showKeyAssist" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="CTRL+SHIFT+L"> + </key> + <key + commandId="org.eclipse.ui.navigate.nextTab" + contextId="org.eclipse.ui.contexts.window" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="ALT+ARROW_RIGHT"> + </key> + <key + commandId="org.eclipse.ui.navigate.previousTab" + contextId="org.eclipse.ui.contexts.window" + schemeId="com.gluster.storage.management.gui.KeyConfig" + sequence="ALT+ARROW_LEFT"> + </key> + <scheme + description="Default Key Bindings Scheme for Gluster Management Console" + id="com.gluster.storage.management.gui.KeyConfig" + name="Gluster"> + </scheme> + </extension> + <extension + id="product" + name="Gluster Management Console" + point="org.eclipse.core.runtime.products"> + <product + application="com.gluster.storage.management.gui.application" + name="Gluster Management Console"> + <property + name="aboutText" + value="GlusterFS is an open source clustered storage solution. The software is a powerful and flexible solution that simplifies the task of managing unstructured file data whether you have a few terabytes of storage or multiple petabytes. Gluster Management Console is a powerful GUI management interface for the GlusterFS."> + </property> + <property + name="windowImages" + value="icons/gluster_icon.png"> + </property> + <property + name="aboutImage" + value="splash/gluster_about.jpg"> + </property> + <property + name="appName" + value="about"> + </property> + <property + name="preferenceCustomization" + value="preferences.ini"> + </property> + </product> + </extension> + <extension + point="org.eclipse.ui.actionSets"> + <actionSet + description="Set of Actions in "Edit" menu" + id="com.gluster.storage.management.gui.actionsets.edit" + label="Edit Action Set" + visible="true"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.PreferencesAction" + definitionId="org.eclipse.ui.window.preferences" + icon="icons/preferences.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Preferences" + menubarPath="com.gluster.storage.management.gui.menu.edit/edit" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Preferences"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.edit" + label="&Edit" + path="additions"> + <groupMarker + name="edit"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed on multiple Volumes" + id="com.gluster.storage.management.gui.actionsets.volumes" + label="Volumes Actions" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.DeleteVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.DeleteVolume" + icon="icons/volume-delete.png" + id="com.gluster.storage.management.gui.actions.DeleteVolumeAction" + label="&Delete Volume(s)" + menubarPath="com.gluster.storage.management.gui.menu.volumes/volumes" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Delete Volume(s)"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.StopVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.StopVolume" + icon="icons/volume-stop.png" + id="com.gluster.storage.management.gui.actions.StopVolumeAction" + label="S&top Volume(s)" + menubarPath="com.gluster.storage.management.gui.menu.volumes/volumes" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Stop Volume(s)"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.StartVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.StartVolume" + icon="icons/volume-start.png" + id="com.gluster.storage.management.gui.actions.StartVolumeAction" + label="&Start Volume(s)" + menubarPath="com.gluster.storage.management.gui.menu.volumes/volumes" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Start Volume(s)"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.CreateVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.CreateVolume" + icon="icons/volume-create.png" + id="com.gluster.storage.management.gui.actions.CreateVolumeAction" + label="&Create Volume" + menubarPath="com.gluster.storage.management.gui.menu.volumes/volumes" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Create a new Volume"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.volumes" + label="&Gluster" + path="additions"> + <groupMarker + name="volumes"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed on a single volume" + id="com.gluster.storage.management.gui.actionsets.volume" + label="Volume Actions" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.MigrateDiskAction" + definitionId="com.gluster.storage.management.gui.commands.MigrateDisk" + icon="icons/disk-migrate.png" + id="com.gluster.storage.management.gui.actions.MigrateDiskAction" + label="&Migrate Disk" + menubarPath="com.gluster.storage.management.gui.menu.glusterserver/glusterserver" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Migrate Disk"> + <enablement> + <objectClass + name="com.gluster.storage.management.core.model.Disk"> + </objectClass> + </enablement> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.DeleteVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.DeleteVolume" + icon="icons/volume-delete.png" + id="com.gluster.storage.management.gui.actions.DeleteVolumeAction" + label="&Delete Volume" + menubarPath="com.gluster.storage.management.gui.menu.volume/volume" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Delete Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.RebalanceVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.RebalanceVolume" + icon="icons/volume-rebalance.png" + id="com.gluster.storage.management.gui.actions.RebalanceVolumeAction" + label="&Rebalance Volume" + menubarPath="com.gluster.storage.management.gui.menu.volume/volume" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Rebalance Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.StopVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.StopVolume" + icon="icons/volume-stop.png" + id="com.gluster.storage.management.gui.actions.StopVolumeAction" + label="S&top Volume" + menubarPath="com.gluster.storage.management.gui.menu.volume/volume" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Stop Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.StartVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.StartVolume" + icon="icons/volume-start.png" + id="com.gluster.storage.management.gui.actions.StartVolumeAction" + label="&Start Volume" + menubarPath="com.gluster.storage.management.gui.menu.volume/volume" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Start Volume"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.volume" + label="&Gluster" + path="additions"> + <groupMarker + name="volume"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed from "Cluster" context" + id="com.gluster.storage.management.gui.actionsets.gluster" + label="Cluster Action Set" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.CreateVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.CreateVolume" + icon="icons/volume-create.png" + id="com.gluster.storage.management.gui.actions.CreateVolumeAction" + label="Create &Volume" + menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Create a new Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.AddServerAction" + definitionId="com.gluster.storage.management.gui.commands.AddServer" + icon="icons/server-add.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="Add &Server(s)" + menubarPath="com.gluster.storage.management.gui.menu.cluster/cluster" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Add Server(s) to Cluster"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.cluster" + label="&Gluster"> + <groupMarker + name="cluster"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed on multiple Gluster Servers" + id="com.gluster.storage.management.gui.actionsets.glusterservers" + label="Gluster Servers Actions" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.RemoveServerAction" + definitionId="com.gluster.storage.management.gui.commands.RemoveServer" + icon="icons/server-remove.png" + id="com.gluster.storage.management.gui.actions.RemoveServerAction" + label="&Remove Server(s)" + menubarPath="com.gluster.storage.management.gui.menu.servers/servers" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Remove Server(s)"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.AddServerAction" + definitionId="com.gluster.storage.management.gui.commands.AddServer" + icon="icons/server-add.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Add Server(s)" + menubarPath="com.gluster.storage.management.gui.menu.servers/servers" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Add Server(s) to Cluster"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.servers" + label="&Gluster" + path="additions"> + <groupMarker + name="servers"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed in the "Gluster Server" contextt; context" + id="com.gluster.storage.management.gui.actionsets.glusterserver" + label="Gluster Server Actions" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.RemoveServerAction" + definitionId="com.gluster.storage.management.gui.commands.RemoveServer" + icon="icons/server-remove.png" + id="com.gluster.storage.management.gui.actions.RemoveServerAction" + label="&Remove Server" + menubarPath="com.gluster.storage.management.gui.menu.glusterserver/glusterserver" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Remove Server"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.glusterserver" + label="&Gluster" + path="additions"> + <groupMarker + name="glusterserver"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed on multiple Discovered Servers" + id="com.gluster.storage.management.gui.actionsets.serversdiscovered" + label="Discovered Servers Actions" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.AddServerAction" + definitionId="com.gluster.storage.management.gui.commands.AddServer" + icon="icons/server-add.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Add Server(s)" + menubarPath="com.gluster.storage.management.gui.menu.discoveredservers/discoveredservers" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Add Server(s) to Cluster"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.discoveredservers" + label="&Gluster" + path="additions"> + <groupMarker + name="discoveredservers"> + </groupMarker> + </menu> + </actionSet> + <actionSet + description="Set of actions that can be performed on single Discovered Server" + id="com.gluster.storage.management.gui.actionsets.serverdiscovered" + label="Discovered Server Actions" + visible="false"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.AddServerAction" + definitionId="com.gluster.storage.management.gui.commands.AddServer" + icon="icons/server-add.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Add Server" + menubarPath="com.gluster.storage.management.gui.menu.discoveredserver/discoveredserver" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Add Server(s) to Cluster"> + </action> + <menu + id="com.gluster.storage.management.gui.menu.discoveredserver" + label="&Gluster" + path="additions"> + <groupMarker + name="discoveredserver"> + </groupMarker> + </menu> + </actionSet> + </extension> + <extension + point="org.eclipse.ui.perspectiveExtensions"> + <perspectiveExtension + targetID="*"> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.NavigationView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="left" + relative="org.eclipse.ui.editorss" + showTitle="false" + standalone="true" + visible="true"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.ClusterSummaryView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="right" + relative="com.gluster.storage.management.gui.views.navigator.NavigationView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.details.DetailsView" + minimized="false" + moveable="false" + ratio="0.70f" + relationship="right" + relative="com.gluster.storage.management.gui.views.navigator.NavigationView" + showTitle="false" + standalone="false" + visible="false"> + </view> + <view + closeable="true" + id="org.eclipse.ui.views.ProgressView" + minimized="false" + moveable="false" + ratio="0.80f" + relationship="bottom" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="true" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.DiscoveredServersView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.DiscoveredServerView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="right" + relative="com.gluster.storage.management.gui.views.navigator.NavigationView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.VolumesSummaryView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.VolumesView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.VolumesSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.VolumeSummaryView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.VolumeDisksView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.VolumeOptionsView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.VolumeLogsView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.GlusterServersSummaryView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.GlusterServersView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.DisksView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.GlusterServerSummaryView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.GlusterServerDisksView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + <view + closeable="false" + id="com.gluster.storage.management.gui.views.GlusterServerLogsView" + minimized="false" + moveable="false" + ratio="0.30f" + relationship="stack" + relative="com.gluster.storage.management.gui.views.ClusterSummaryView" + showTitle="true" + standalone="false" + visible="false"> + </view> + </perspectiveExtension> + </extension> + <extension + point="org.eclipse.ui.decorators"> + <decorator + adaptable="false" + class="com.gluster.storage.management.gui.views.navigator.NavigationTreeLabelDecorator" + id="com.gluster.storage.management.gui.views.navigator.decorator" + label="Navigation Tree Decorator" + lightweight="true" + location="BOTTOM_LEFT" + state="true"> + </decorator> + </extension> + <extension + point="org.eclipse.ui.preferencePages"> + <page + class="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" + id="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" + name="Gluster"> + </page> + <page + category="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" + class="com.gluster.storage.management.gui.preferences.ClusterPreferencePage" + id="com.gluster.storage.management.gui.preferences.ClusterPreferencePage" + name="Cluster"> + </page> + <page + category="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" + class="com.gluster.storage.management.gui.preferences.ConsolePreferencePage" + id="com.gluster.storage.management.gui.preferences.ConsolePreferencePage" + name="Console"> + </page> + <page + category="com.gluster.storage.management.gui.preferences.GlusterPreferencePage" + class="org.eclipse.ui.ExtensionFactory:newKeysPreferencePage" + id="org.eclipse.ui.NewKeysPreferencePage" + name="Keys"> + </page> + </extension> + <extension + point="org.eclipse.core.runtime.preferences"> + <initializer + class="com.gluster.storage.management.gui.preferences.PreferenceInitializer"> + </initializer> + </extension> + <extension + point="org.eclipse.ui.popupMenus"> + <objectContribution + id="gluster.context.menu.glusterserver" + objectClass="com.gluster.storage.management.core.model.GlusterServer"> + <action + class="com.gluster.storage.management.gui.actions.RemoveServerAction" + definitionId="com.gluster.storage.management.gui.commands.RemoveServer" + enablesFor="1" + icon="icons/server-remove.png" + id="com.gluster.storage.management.gui.actions.RemoveServerAction" + label="&Remove Server" + menubarPath="additions"> + </action> + </objectContribution> + <objectContribution + id="gluster.context.menu.volume" + objectClass="com.gluster.storage.management.core.model.Volume"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.MigrateDiskAction" + definitionId="com.gluster.storage.management.gui.commands.MigrateDisk" + icon="icons/disk-migrate.png" + id="com.gluster.storage.management.gui.actions.MigrateDiskAction" + label="&Migrate Disk" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Migrate Disk"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.DeleteVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.DeleteVolume" + icon="icons/volume-delete.png" + id="com.gluster.storage.management.gui.actions.DeleteVolumeAction" + label="&Delete Volume" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Delete Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.RebalanceVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.RebalanceVolume" + icon="icons/volume-rebalance.png" + id="com.gluster.storage.management.gui.actions.RebalanceVolumeAction" + label="&Rebalance Volume" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Rebalance Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.StopVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.StopVolume" + icon="icons/volume-stop.png" + id="com.gluster.storage.management.gui.actions.StopVolumeAction" + label="S&top Volume" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Stop Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.StartVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.StartVolume" + icon="icons/volume-start.png" + id="com.gluster.storage.management.gui.actions.StartVolumeAction" + label="&Start Volume" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Start Volume"> + </action> + </objectContribution> + <objectContribution + id="gluster.context.menu.server" + objectClass="com.gluster.storage.management.core.model.Server"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.AddServerAction" + definitionId="com.gluster.storage.management.gui.commands.AddServer" + enablesFor="+" + icon="icons/server-add.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Add Server(s)" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Add Server(s) to Cluster"> + </action> + <visibility> + <not> + <objectClass + name="com.gluster.storage.management.core.model.GlusterServer"> + </objectClass> + </not> + </visibility> + </objectContribution> + <objectContribution + id="gluster.context.menu.entityGroup" + objectClass="com.gluster.storage.management.core.model.EntityGroup"> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.CreateVolumeAction" + definitionId="com.gluster.storage.management.gui.commands.CreateVolume" + icon="icons/volume-create.png" + id="com.gluster.storage.management.gui.actions.CreateVolumeAction" + label="&Create Volume" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Create a new Volume"> + </action> + <action + allowLabelUpdate="false" + class="com.gluster.storage.management.gui.actions.AddServerAction" + definitionId="com.gluster.storage.management.gui.commands.AddServer" + icon="icons/server-add.png" + id="com.gluster.storage.management.gui.actions.AddServerAction" + label="&Add Server(s)" + menubarPath="additions" + mode="FORCE_TEXT" + pulldown="false" + retarget="false" + state="false" + style="push" + toolbarPath="Normal" + tooltip="Add Server(s) to Cluster"> + </action> + </objectContribution> + </extension> + +</plugin> diff --git a/src/com.gluster.storage.management.gui/preferences.ini b/src/com.gluster.storage.management.gui/preferences.ini new file mode 100644 index 00000000..91228592 --- /dev/null +++ b/src/com.gluster.storage.management.gui/preferences.ini @@ -0,0 +1 @@ +org.eclipse.ui/KEY_CONFIGURATION_ID = com.gluster.storage.management.gui.KeyConfig
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/splash.bmp b/src/com.gluster.storage.management.gui/splash.bmp Binary files differnew file mode 100644 index 00000000..059c28f9 --- /dev/null +++ b/src/com.gluster.storage.management.gui/splash.bmp diff --git a/src/com.gluster.storage.management.gui/splash/gluster_about.jpg b/src/com.gluster.storage.management.gui/splash/gluster_about.jpg Binary files differnew file mode 100644 index 00000000..242fa560 --- /dev/null +++ b/src/com.gluster.storage.management.gui/splash/gluster_about.jpg diff --git a/src/com.gluster.storage.management.gui/splash/splash-dialog.bmp b/src/com.gluster.storage.management.gui/splash/splash-dialog.bmp Binary files differnew file mode 100644 index 00000000..2de2897f --- /dev/null +++ b/src/com.gluster.storage.management.gui/splash/splash-dialog.bmp diff --git a/src/com.gluster.storage.management.gui/splash/splash-dialog.png b/src/com.gluster.storage.management.gui/splash/splash-dialog.png Binary files differnew file mode 100644 index 00000000..789eafb0 --- /dev/null +++ b/src/com.gluster.storage.management.gui/splash/splash-dialog.png diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Activator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Activator.java new file mode 100644 index 00000000..3fa5bcf0 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Activator.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + // The plug-in ID + public static final String PLUGIN_ID = "com.gluster.storage.management.gui"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + public void editorOpened() { + System.err.println("Editor opened!"); + } + + /** + * The constructor + */ + public Activator() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext context) throws Exception { + super.start(context); + plugin = this; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java new file mode 100644 index 00000000..50dbd314 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Application.java @@ -0,0 +1,116 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.databinding.observable.Realm; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.gui.login.LoginDialog; + +/** + * This class controls all aspects of the application's execution + */ +public class Application implements IApplication { + + public static final String PLUGIN_ID = "com.gluster.storage.management.gui"; + private static Application instance; + private List<IEntityListener> entityListeners = Collections.synchronizedList(new ArrayList<IEntityListener>()); + + public Application() { + instance = this; + } + + public static Application getApplication() { + return instance; + } + + private boolean login() { + LoginDialog loginDialog = new LoginDialog(new Shell(Display.getDefault())); + return (loginDialog.open() == Window.OK); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext) + */ + public Object start(IApplicationContext context) { + Display display = PlatformUI.createDisplay(); + + final boolean[] loginSuccess = new boolean[1]; + Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { + public void run() { + loginSuccess[0] = login(); + } + }); + + if (!loginSuccess[0]) { + return IApplication.EXIT_OK; + } + try { + int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor()); + if (returnCode == PlatformUI.RETURN_RESTART) { + return IApplication.EXIT_RESTART; + } + return IApplication.EXIT_OK; + } finally { + display.dispose(); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.equinox.app.IApplication#stop() + */ + public void stop() { + if (!PlatformUI.isWorkbenchRunning()) + return; + final IWorkbench workbench = PlatformUI.getWorkbench(); + final Display display = workbench.getDisplay(); + display.syncExec(new Runnable() { + public void run() { + if (!display.isDisposed()) + workbench.close(); + } + }); + } + + public void addEntityListener(IEntityListener listener) { + entityListeners.add(listener); + } + + public void entityChanged(Entity entity, String[] paremeters) { + for (IEntityListener listener : entityListeners) { + listener.entityChanged(entity, paremeters); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationActionBarAdvisor.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationActionBarAdvisor.java new file mode 100644 index 00000000..3f6cb7d5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationActionBarAdvisor.java @@ -0,0 +1,94 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.GroupMarker; +import org.eclipse.jface.action.ICoolBarManager; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.ui.IWorkbenchActionConstants; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.actions.ActionFactory; +import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import com.gluster.storage.management.gui.utils.GUIHelper; + +/** + * An action bar advisor is responsible for creating, adding, and disposing of the actions added to a workbench window. + * Each window will be populated with new actions. + */ +public class ApplicationActionBarAdvisor extends ActionBarAdvisor { + private IWorkbenchWindow window; + /* + * Actions - important to allocate these only in makeActions, and then use them in the fill methods. This ensures + * that the actions aren't recreated when fillActionBars is called with FILL_PROXY. + */ + private IWorkbenchAction exitAction; + private IWorkbenchAction aboutAction; + + private GUIHelper guiHelper = GUIHelper.getInstance(); + + public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) { + super(configurer); + } + + protected void makeActions(final IWorkbenchWindow window) { + this.window = window; + /* + * Creates the actions and registers them. Registering is needed to ensure that key bindings work. The + * corresponding commands keybindings are defined in the plugin.xml file. Registering also provides automatic + * disposal of the actions when the window is closed. + */ + exitAction = ActionFactory.QUIT.create(window); + register(exitAction); + + aboutAction = ActionFactory.ABOUT.create(window); + aboutAction.setText("&About"); + aboutAction.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.HELP)); + register(aboutAction); + } + + protected void fillMenuBar(IMenuManager menuBar) { + // File + MenuManager fileMenu = new MenuManager("&File", IWorkbenchActionConstants.M_FILE); + fileMenu.add(new Separator()); + fileMenu.add(exitAction); + + // Help + MenuManager helpMenu = new MenuManager("&Help", IWorkbenchActionConstants.M_HELP); + helpMenu.add(aboutAction); + + menuBar.add(fileMenu); + // Add a group marker indicating where action set menus will appear. + // All action sets from plugin.xml will get added here + menuBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + menuBar.add(helpMenu); + } + + protected void fillCoolBar(ICoolBarManager coolBar) { + // All our actions are added to toolbar through the extension point org.eclipse.ui.actionSets + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationWorkbenchAdvisor.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationWorkbenchAdvisor.java new file mode 100644 index 00000000..07e20466 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationWorkbenchAdvisor.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.ui.application.IWorkbenchConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchAdvisor; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** + * This workbench advisor creates the window advisor, and specifies + * the perspective id for the initial window. + */ +public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { + return new ApplicationWorkbenchWindowAdvisor(configurer); + } + + public String getInitialWindowPerspectiveId() { + return Perspective.ID; + } + + @Override + public void initialize(IWorkbenchConfigurer configurer) { + super.initialize(configurer); + configurer.setSaveAndRestore(false); // we don't need save/restore as of now + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationWorkbenchWindowAdvisor.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationWorkbenchWindowAdvisor.java new file mode 100644 index 00000000..722821f7 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ApplicationWorkbenchWindowAdvisor.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.swt.graphics.Point; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { + private final static int DEFAULT_WIDTH = 1024; + private final static int DEFAULT_HEIGHT = 768; + private final GUIHelper guiHelper = GUIHelper.getInstance(); + + public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { + super(configurer); + } + + @Override + public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) { + return new ApplicationActionBarAdvisor(configurer); + } + + @Override + public void preWindowOpen() { + super.preWindowOpen(); + + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + configurer.setInitialSize(new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT)); + configurer.setShowCoolBar(true); + configurer.setShowStatusLine(true); + configurer.setShowMenuBar(true); + configurer.setShowProgressIndicator(true); // shows progress indicator in status bar + } + + @Override + public void postWindowCreate() { + super.postWindowCreate(); + guiHelper.centerShellInScreen(getWindowConfigurer().getWindow().getShell()); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java new file mode 100644 index 00000000..92553797 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/DiskTableLabelProvider.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.swt.graphics.Image; + +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.DisksPage.DISK_TABLE_COLUMN_INDICES; + +public class DiskTableLabelProvider extends TableLabelProviderAdapter { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (!(element instanceof Disk)) { + return null; + } + + Disk disk = (Disk) element; + if (columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { + DISK_STATUS status = disk.getStatus(); + switch (status) { + case READY: + return guiHelper.getImage(IImageKeys.STATUS_ONLINE); + case OFFLINE: + return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); + case UNINITIALIZED: + return guiHelper.getImage(IImageKeys.DISK_UNINITIALIZED); + case INITIALIZING: + return guiHelper.getImage(IImageKeys.WORK_IN_PROGRESS); + default: + throw new GlusterRuntimeException("Invalid disk status [" + status + "]"); + } + } + + return null; + } + + private String getDiskSpaceInUse(Disk disk) { + if (disk.isReady()) { + return NumberUtil.formatNumber(disk.getSpaceInUse()); + } else { + return "NA"; + } + } + + private String getDiskSpace(Disk disk) { + if (disk.isOffline()) { + return "NA"; + } else { + return NumberUtil.formatNumber(disk.getSpace()); + } + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Disk)) { + return null; + } + + Disk disk = (Disk) element; + return (columnIndex == DISK_TABLE_COLUMN_INDICES.SERVER.ordinal() ? disk.getServerName() + : columnIndex == DISK_TABLE_COLUMN_INDICES.DISK.ordinal() ? disk.getName() + : columnIndex == DISK_TABLE_COLUMN_INDICES.SPACE.ordinal() ? getDiskSpace(disk) + : columnIndex == DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE.ordinal() ? getDiskSpaceInUse(disk) + : columnIndex == DISK_TABLE_COLUMN_INDICES.STATUS.ordinal() ? disk.getStatusStr() : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/EntityGroupContentProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/EntityGroupContentProvider.java new file mode 100644 index 00000000..26848eef --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/EntityGroupContentProvider.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.gluster.storage.management.core.model.EntityGroup; + +public class EntityGroupContentProvider<T> implements + IStructuredContentProvider { + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + @SuppressWarnings("rawtypes") + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof EntityGroup) { + return ((EntityGroup) inputElement).getChildren().toArray(); + } + return null; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java new file mode 100644 index 00000000..3fc2dfa0 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/GlusterServerTableLabelProvider.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.swt.graphics.Image; + +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.GlusterServersPage.GLUSTER_SERVER_TABLE_COLUMN_INDICES; + +public class GlusterServerTableLabelProvider extends TableLabelProviderAdapter { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (!(element instanceof GlusterServer)) { + return null; + } + + GlusterServer server = (GlusterServer) element; + if(columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.STATUS.ordinal()) { + SERVER_STATUS status = server.getStatus(); + if(status == SERVER_STATUS.ONLINE) { + return guiHelper.getImage(IImageKeys.STATUS_ONLINE); + } else { + return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); + } + } + + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof GlusterServer)) { + return null; + } + + GlusterServer server = (GlusterServer) element; + + if (server.getStatus() == SERVER_STATUS.OFFLINE + && columnIndex != GLUSTER_SERVER_TABLE_COLUMN_INDICES.NAME.ordinal() + && columnIndex != GLUSTER_SERVER_TABLE_COLUMN_INDICES.STATUS.ordinal()) { + return "NA"; + } + + return (columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.NAME.ordinal() ? server.getName() + : columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.STATUS.ordinal() ? server.getStatusStr() + // : columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.PREFERRED_NETWORK.ordinal() ? server.getPreferredNetworkInterface().getName() + : columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.NUM_OF_CPUS.ordinal() ? "" + server.getNumOfCPUs() + //: columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.CPU_USAGE.ordinal() ? "" + server.getCpuUsage() + : columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_MEMORY.ordinal() ? "" + server.getTotalMemory() + //: columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.MEMORY_IN_USE.ordinal() ? "" + server.getMemoryInUse() + : columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_DISK_SPACE.ordinal() ? NumberUtil.formatNumber(server.getTotalDiskSpace()) + : columnIndex == GLUSTER_SERVER_TABLE_COLUMN_INDICES.IP_ADDRESSES.ordinal() ? server.getIpAddressesAsString() : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ICommandIds.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ICommandIds.java new file mode 100644 index 00000000..d9cb434c --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ICommandIds.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +/** + * Interface defining the application's command IDs. + * Key bindings can be defined for specific commands. + * To associate an action with a command, use IAction.setActionDefinitionId(commandId). + * + * @see org.eclipse.jface.action.IAction#setActionDefinitionId(String) + */ +public interface ICommandIds { + + public static final String CMD_OPEN = "com.gluster.storage.management.gui.open"; + public static final String CMD_OPEN_MESSAGE = "com.gluster.storage.management.gui.openMessage"; + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IEntityListener.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IEntityListener.java new file mode 100644 index 00000000..98dfbe9a --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IEntityListener.java @@ -0,0 +1,37 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import com.gluster.storage.management.core.model.Entity; + +/** + * Any class that is interested in changes to entities in application scope should implement this interface and register + * with the application using {@link Application#addEntityListener(IEntityListener)} + * + * @author root + * + */ +public interface IEntityListener { + /** + * This method is called whenever any attribute of an entity in application scope changes + * @param entity Entity that has changed + * @param paremeters List of attribute names that have changed. This can be null. + */ + public void entityChanged(Entity entity, String[] paremeters); +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java new file mode 100644 index 00000000..fd5972c5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/IImageKeys.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +public interface IImageKeys { + public static final String CLUSTER = "icons/cluster.png"; + public static final String VOLUMES = "icons/volumes.png"; + public static final String SERVERS = "icons/servers.png"; + public static final String VOLUME = "icons/volume.png"; + public static final String SERVER = "icons/server.png"; + public static final String GSN = "icons/gsn.png"; + public static final String SETTINGS = "icons/settings.png"; + public static final String ADD = "icons/plus-white.png"; + public static final String REMOVE = "icons/minus-white.png"; + public static final String CREATE_VOLUME = "icons/volume-create.png"; + public static final String CREATE_VOLUME_BIG = "icons/volume-create-big.png"; + public static final String REMOVE_VOLUME = "icons/volume-delete.png"; + public static final String ADD_SERVER = "icons/server-add.png"; + public static final String ADD_SERVER_BIG = "icons/server-add-big.png"; + public static final String REMOVE_SERVER = "icons/server-remove.png"; + public static final String HELP = "icons/question.png"; + public static final String STATUS_OFFLINE = "icons/status-offline.png"; + public static final String STATUS_ONLINE = "icons/status-online.png"; + public static final String STATUS_CANCELLED = "icons/status-offline.png"; + public static final String STATUS_SUCCESS = "icons/status-online.png"; + public static final String WORK_IN_PROGRESS = "icons/progress-bar.png"; + public static final String CHECKBOX_UNCHECKED = "icons/ui-check-box-uncheck.png"; + public static final String CHECKBOX_CHECKED = "icons/ui-check-box.png"; + public static final String DISK_UNINITIALIZED = "icons/disk-uninitialized.png"; + public static final String SEARCH = "icons/search.png"; + public static final String ARROW_UP = "icons/arrow-up.png"; + public static final String ARROW_DOWN = "icons/arrow-down.png"; + + public static final String OVERLAY_OFFLINE = "icons/status-offline-small.png"; + public static final String OVERLAY_ONLINE = "icons/status-online-small.png"; + public static final String OVERLAY_STAR = "icons/star-small.png"; + + public static final String SPLASH_IMAGE = "splash.bmp"; + public static final String DIALOG_SPLASH_IMAGE = "splash/splash-dialog.bmp"; + + public static final String PROGRESS_BAR_LEFT = "images/progress_image_left.png"; + public static final String PROGRESS_BAR_RIGHT = "images/progress_image_right.png"; + public static final String PROGRESS_BAR_FILLED = "images/progress_image_filled_safe.png"; + public static final String PROGRESS_BAR_EMPTY = "images/progress_image_empty.png"; + public static final String GAUGE_SMALL = "images/gauge_small.png"; +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/NetworkInterfaceTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/NetworkInterfaceTableLabelProvider.java new file mode 100644 index 00000000..d7b700d4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/NetworkInterfaceTableLabelProvider.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + + +import com.gluster.storage.management.core.model.NetworkInterface; +import com.gluster.storage.management.gui.views.details.tabcreators.GlusterServerTabCreator.NETWORK_INTERFACE_TABLE_COLUMN_INDICES; + +public class NetworkInterfaceTableLabelProvider extends TableLabelProviderAdapter { + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof NetworkInterface)) { + return null; + } + + NetworkInterface networkInterface = (NetworkInterface) element; + return (columnIndex == NETWORK_INTERFACE_TABLE_COLUMN_INDICES.INTERFACE.ordinal() ? networkInterface.getName() + : columnIndex == NETWORK_INTERFACE_TABLE_COLUMN_INDICES.IP_ADDRESS.ordinal() ? networkInterface.getIpAddress() + : columnIndex == NETWORK_INTERFACE_TABLE_COLUMN_INDICES.NETMASK.ordinal() ? networkInterface.getNetMask() + : columnIndex == NETWORK_INTERFACE_TABLE_COLUMN_INDICES.GATEWAY.ordinal() ? networkInterface.getDefaultGateway() + // : columnIndex == NETWORK_INTERFACE_TABLE_COLUMN_INDICES.PREFERRED.ordinal() ? (networkInterface.isPreferred() ? "Yes" : "No") + : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Perspective.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Perspective.java new file mode 100644 index 00000000..3f8702ce --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/Perspective.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +import com.gluster.storage.management.gui.views.DetailsView; +import com.gluster.storage.management.gui.views.NavigationView; + +public class Perspective implements IPerspectiveFactory { + + /** + * The ID of the perspective as specified in the extension. + */ + public static final String ID = "com.gluster.storage.management.gui.perspective"; + + public void createInitialLayout(IPageLayout layout) { + layout.setEditorAreaVisible(false); + //layout.addStandaloneView(ClusterView.ID, false, IPageLayout.LEFT, 0.30f, layout.getEditorArea()); + //layout.addStandaloneView(DetailsView.ID, false, IPageLayout.RIGHT, 0.70f, layout.getEditorArea()); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java new file mode 100644 index 00000000..cd5fab62 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerDiskTableLabelProvider.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.swt.graphics.Image; + +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.ServerDisksPage.SERVER_DISK_TABLE_COLUMN_INDICES; + +public class ServerDiskTableLabelProvider extends TableLabelProviderAdapter { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (!(element instanceof Disk)) { + return null; + } + + Disk disk = (Disk) element; + if (columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal()) { + DISK_STATUS status = disk.getStatus(); + switch (status) { + case READY: + return guiHelper.getImage(IImageKeys.STATUS_ONLINE); + case OFFLINE: + return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); + case UNINITIALIZED: + return guiHelper.getImage(IImageKeys.DISK_UNINITIALIZED); + case INITIALIZING: + return guiHelper.getImage(IImageKeys.WORK_IN_PROGRESS); + default: + throw new GlusterRuntimeException("Invalid disk status [" + status + "]"); + } + } + + return null; + } + + private String getDiskSpaceInUse(Disk disk) { + if(disk.isReady()) { + return NumberUtil.formatNumber(disk.getSpaceInUse()); + } else { + return "NA"; + } + } + + private String getDiskSpace(Disk disk) { + if(disk.isOffline()) { + return "NA"; + } else { + return NumberUtil.formatNumber(disk.getSpace()); + } + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Disk)) { + return null; + } + + + Disk disk = (Disk) element; + return (columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.DISK.ordinal() ? disk.getName() + : columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.SPACE.ordinal() ? getDiskSpace(disk) + : columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE.ordinal() ? getDiskSpaceInUse(disk) + : columnIndex == SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal() ? disk.getStatusStr() + : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerTableLabelProvider.java new file mode 100644 index 00000000..6ec446cc --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/ServerTableLabelProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + + +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.pages.ServersPage.SERVER_TABLE_COLUMN_INDICES; + +public class ServerTableLabelProvider extends TableLabelProviderAdapter { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Server)) { + return null; + } + + Server server = (Server) element; + return (columnIndex == SERVER_TABLE_COLUMN_INDICES.NAME.ordinal() ? server.getName() + : columnIndex == SERVER_TABLE_COLUMN_INDICES.IP_ADDRESSES.ordinal() ? server.getIpAddressesAsString() + : columnIndex == SERVER_TABLE_COLUMN_INDICES.NUM_OF_DISKS.ordinal() ? "" + server.getNumOfDisks() + : columnIndex == SERVER_TABLE_COLUMN_INDICES.TOTAL_DISK_SPACE.ordinal() ? NumberUtil.formatNumber(server.getTotalDiskSpace()) +// : columnIndex == SERVER_TABLE_COLUMN_INDICES.NUM_OF_CPUS.ordinal() ? "" + server.getNumOfCPUs() +// : columnIndex == SERVER_TABLE_COLUMN_INDICES.CPU_USAGE.ordinal() ? "" + server.getCpuUsage() +// : columnIndex == SERVER_TABLE_COLUMN_INDICES.TOTAL_MEMORY.ordinal() ? "" + server.getTotalMemory() +// : columnIndex == SERVER_TABLE_COLUMN_INDICES.MEMORY_IN_USE.ordinal() ? "" + server.getMemoryInUse() +// : columnIndex == SERVER_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE.ordinal() ? "" + server.getDiskSpaceInUse() + : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TableLabelProviderAdapter.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TableLabelProviderAdapter.java new file mode 100644 index 00000000..95d6fde4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/TableLabelProviderAdapter.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.graphics.Image; + +public class TableLabelProviderAdapter implements ITableLabelProvider { + + @Override + public void addListener(ILabelProviderListener listener) { + // do nothing + + } + + @Override + public void dispose() { + // do nothing + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return true; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + // do nothing + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + return null; + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java new file mode 100644 index 00000000..399cdc65 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeLogTableLabelProvider.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.LogMessage; +import com.gluster.storage.management.core.utils.DateUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.VolumeLogsPage.LOG_TABLE_COLUMN_INDICES; + +public class VolumeLogTableLabelProvider extends TableLabelProviderAdapter { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + private String getFormattedDiskName(Disk disk) { + return disk.getServerName() + ":" + disk.getName(); + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof LogMessage)) { + return null; + } + + LogMessage logMessage = (LogMessage) element; + return (columnIndex == LOG_TABLE_COLUMN_INDICES.DATE.ordinal() ? DateUtil.formatDate(logMessage.getTimestamp()) + : columnIndex == LOG_TABLE_COLUMN_INDICES.TIME.ordinal() ? DateUtil.formatTime(logMessage.getTimestamp()) + : columnIndex == LOG_TABLE_COLUMN_INDICES.DISK.ordinal() ? getFormattedDiskName(logMessage.getDisk()) + : columnIndex == LOG_TABLE_COLUMN_INDICES.SEVERITY.ordinal() ? "" + logMessage.getSeverity() + : columnIndex == LOG_TABLE_COLUMN_INDICES.MESSAGE.ordinal() ? logMessage.getMessage() : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java new file mode 100644 index 00000000..cf1ceaf7 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeOptionsTableLabelProvider.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import java.util.Map.Entry; + +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.VolumeOptionsPage.OPTIONS_TABLE_COLUMN_INDICES; + +public class VolumeOptionsTableLabelProvider extends TableLabelProviderAdapter { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Entry)) { + return null; + } + + Entry<String, String> entry = (Entry) element; + String key = entry.getKey(); + String value = entry.getValue(); + return (columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY.ordinal() ? key + : columnIndex == OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE.ordinal() ? value + : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeTableLabelProvider.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeTableLabelProvider.java new file mode 100644 index 00000000..b0f0c8d0 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/VolumeTableLabelProvider.java @@ -0,0 +1,82 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui; + +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.pages.VolumesPage.VOLUME_TABLE_COLUMN_INDICES; + +public class VolumeTableLabelProvider implements ITableLabelProvider { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + if (!(element instanceof Volume)) { + return null; + } + + Volume volume = (Volume) element; + if(columnIndex == VOLUME_TABLE_COLUMN_INDICES.VOLUME_STATUS.ordinal()) { + VOLUME_STATUS status = volume.getStatus(); + if(status == VOLUME_STATUS.ONLINE) { + return guiHelper.getImage(IImageKeys.STATUS_ONLINE); + } else { + return guiHelper.getImage(IImageKeys.STATUS_OFFLINE); + } + } + + return null; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Volume)) { + return null; + } + + Volume volume = (Volume) element; + return (columnIndex == VOLUME_TABLE_COLUMN_INDICES.NAME.ordinal() ? volume.getName() + : columnIndex == VOLUME_TABLE_COLUMN_INDICES.VOLUME_TYPE.ordinal() ? volume.getVolumeTypeStr() + : columnIndex == VOLUME_TABLE_COLUMN_INDICES.TRANSPORT_TYPE.ordinal() ? volume.getTransportTypeStr() + : columnIndex == VOLUME_TABLE_COLUMN_INDICES.NUM_OF_DISKS.ordinal() ? "" + volume.getNumOfDisks() + : columnIndex == VOLUME_TABLE_COLUMN_INDICES.VOLUME_STATUS.ordinal() ? volume.getStatusStr() : "Invalid"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java new file mode 100644 index 00000000..4aa387bc --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AbstractActionDelegate.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +import com.gluster.storage.management.core.model.Entity; + +/** + * All action delegates in the application should extend from this class. It provides common functionality of grabbing + * the Window object on initialization and extracting the selected entity in case of selection change on the navigation + * tree. + */ +public abstract class AbstractActionDelegate implements IWorkbenchWindowActionDelegate { + protected IWorkbenchWindow window; + protected Entity selectedEntity; + + @Override + public void selectionChanged(IAction action, ISelection selection) { + if (selection instanceof StructuredSelection) { + Entity selectedEntity = (Entity) ((StructuredSelection) selection).getFirstElement(); + + if (this.selectedEntity == selectedEntity) { + // entity selection has not changed. do nothing. + return; + } + + if(selectedEntity != null) { + this.selectedEntity = selectedEntity; + } + } + } + + @Override + public void init(IWorkbenchWindow window) { + this.window = window; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java new file mode 100644 index 00000000..7957b6f0 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/AddServerAction.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Display; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.GlusterServersClient; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServerResponse; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Volume; + +public class AddServerAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + GlusterServersClient glusterServersClient = new GlusterServersClient(modelManager.getSecurityToken()); + Server server = (Server) selectedEntity; + GlusterServerResponse response = glusterServersClient.addServer(server); + if (response.getStatus().isSuccess()) { + modelManager.removeDiscoveredServer(server); + modelManager.addGlusterServer(response.getGlusterServer()); + new MessageDialog(Display.getDefault().getActiveShell(), "Add Server", null, "Server [" + server.getName() + + "] added successfully!", MessageDialog.INFORMATION, new String[] { "OK" }, 0).open(); + } else { + new MessageDialog(Display.getDefault().getActiveShell(), "Add Server", null, "Server [" + server.getName() + + " could not be added to cluster! Error: [" + response.getStatus().getMessage() + "]", + MessageDialog.ERROR, new String[] { "OK" }, 0).open(); + } + } + + @Override + public void dispose() { + System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); + } + + @SuppressWarnings("rawtypes") + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + if (selectedEntity != null && selectedEntity instanceof Entity) { + action.setEnabled(true); + if (selectedEntity instanceof EntityGroup && ((EntityGroup) selectedEntity).getEntityType() == Volume.class) { + action.setEnabled(false); + } + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java new file mode 100644 index 00000000..266db0af --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/CreateVolumeAction.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.widgets.Display; + +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.dialogs.CreateVolumeWizard; + +public class CreateVolumeAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + CreateVolumeWizard wizard = new CreateVolumeWizard(); + + WizardDialog dialog = new WizardDialog(window.getShell(), wizard); + dialog.create(); + dialog.getShell().setSize(500, 550); + dialog.open(); + } + }); + } + + @Override + public void dispose() { + window = null; + } + + @SuppressWarnings("rawtypes") + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + action.setEnabled(true); + if(selectedEntity instanceof EntityGroup && ((EntityGroup)selectedEntity).getEntityType() != Volume.class) { + // selected entity is either "servers" or "discovered servers". + action.setEnabled(false); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java new file mode 100644 index 00000000..b4b92c31 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/DeleteVolumeAction.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; + +public class DeleteVolumeAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + System.out.println("Running [" + this.getClass().getSimpleName() + "]"); + } + + @Override + public void dispose() { + System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/EditVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/EditVolumeAction.java new file mode 100644 index 00000000..6f3fdf24 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/EditVolumeAction.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; + +public class EditVolumeAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + System.out.println("Running [" + this.getClass().getSimpleName() + "]"); + } + + @Override + public void dispose() { + System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/IActionSetIDs.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/IActionSetIDs.java new file mode 100644 index 00000000..6c54bae8 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/IActionSetIDs.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +public interface IActionSetIDs { + public static final String ACTION_SET_CLUSTER = "com.gluster.storage.management.gui.actionsets.gluster"; + public static final String ACTION_SET_VOLUMES = "com.gluster.storage.management.gui.actionsets.volumes"; + public static final String ACTION_SET_VOLUME = "com.gluster.storage.management.gui.actionsets.volume"; + public static final String ACTION_SET_DISKS = "com.gluster.storage.management.gui.actionsets.disks"; + public static final String ACTION_SET_DISK = "com.gluster.storage.management.gui.actionsets.disk"; + public static final String ACTION_SET_GLUSTER_SERVERS = "com.gluster.storage.management.gui.actionsets.glusterservers"; + public static final String ACTION_SET_GLUSTER_SERVER = "com.gluster.storage.management.gui.actionsets.glusterserver"; + public static final String ACTION_SET_DISCOVERED_SERVERS = "com.gluster.storage.management.gui.actionsets.serversdiscovered"; + public static final String ACTION_SET_DISCOVERED_SERVER = "com.gluster.storage.management.gui.actionsets.serverdiscovered"; + + public static final String ACTION_SET_EDIT = "com.gluster.storage.management.gui.actionsets.edit"; +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java new file mode 100644 index 00000000..75be4e6b --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateDiskAction.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.wizard.WizardDialog; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.dialogs.MigrateDiskWizard; + +public class MigrateDiskAction extends AbstractActionDelegate { + private Volume volume; + private Disk disk; + + @Override + public void run(IAction action) { +// MigrateDiskDialog dialog = new MigrateDiskDialog(window.getShell(), volume, disk); +// dialog.create(); +// dialog.open(); + MigrateDiskWizard wizard = new MigrateDiskWizard(volume, disk); + + WizardDialog dialog = new WizardDialog(window.getShell(), wizard); + dialog.create(); + dialog.getShell().setSize(1024, 600); + dialog.open(); + } + + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + if (selectedEntity instanceof Volume) { + volume = (Volume) selectedEntity; + } + + action.setEnabled(false); + if (selectedEntity instanceof Disk) { + disk = (Disk) selectedEntity; + action.setEnabled(((StructuredSelection) selection).size() == 1); + } + } + + @Override + public void dispose() { + // TODO Auto-generated method stub + + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateVolumeAction.java new file mode 100644 index 00000000..97f1c79b --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/MigrateVolumeAction.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; + +public class MigrateVolumeAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + System.out.println("Running [" + this.getClass().getSimpleName() + "]"); + } + + @Override + public void dispose() { + System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PreferencesAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PreferencesAction.java new file mode 100644 index 00000000..f6fd88e4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/PreferencesAction.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.ui.actions.ActionFactory; + +public class PreferencesAction extends AbstractActionDelegate { + + @Override + public void dispose() { + + } + + @Override + public void run(IAction action) { + ActionFactory.PREFERENCES.create(window).run(); + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java new file mode 100644 index 00000000..65227b0b --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RebalanceVolumeAction.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; + +public class RebalanceVolumeAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + System.out.println("Running [" + this.getClass().getSimpleName() + "]"); + } + + @Override + public void dispose() { + System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java new file mode 100644 index 00000000..d5d42363 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/RemoveServerAction.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowActionDelegate; + +public class RemoveServerAction extends AbstractActionDelegate { + @Override + public void run(IAction action) { + System.out.println("Running [" + this.getClass().getSimpleName() + "]"); + } + + @Override + public void dispose() { + System.out.println("Disposing [" + this.getClass().getSimpleName() + "]"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StartVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StartVolumeAction.java new file mode 100644 index 00000000..cc0fbe94 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StartVolumeAction.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Display; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; + +public class StartVolumeAction extends AbstractActionDelegate { + private Volume volume; + private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + + @Override + public void run(final IAction action) { + if (volume.getStatus() == VOLUME_STATUS.ONLINE) { + return; // Volume already online. Don't do anything. + } + + VolumesClient client = new VolumesClient(modelManager.getSecurityToken()); + final Status status = client.startVolume(volume.getName()); + final String actionDesc = action.getDescription(); + final Display display = Display.getDefault(); + display.asyncExec(new Runnable() { + + @Override + public void run() { + if (status.isSuccess()) { + new MessageDialog(display.getActiveShell(), actionDesc, null, "Volume [" + + volume.getName() + "] started successfully!", MessageDialog.INFORMATION, + new String[] { "OK" }, 0).open(); + modelManager.updateVolumeStatus(volume, VOLUME_STATUS.ONLINE); + } else { + new MessageDialog(display.getActiveShell(), actionDesc, null, "Volume [" + + volume.getName() + "] could not be started! Error: [" + status + "]", + MessageDialog.ERROR, new String[] { "OK" }, 0).open(); + } + } + }); + } + + @Override + public void dispose() { + + } + + /* + * (non-Javadoc) + * + * @see + * com.gluster.storage.management.gui.actions.AbstractActionDelegate#selectionChanged(org.eclipse.jface.action.IAction + * , org.eclipse.jface.viewers.ISelection) + */ + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + if (selectedEntity instanceof Volume) { + volume = (Volume) selectedEntity; + action.setEnabled(volume.getStatus() == VOLUME_STATUS.OFFLINE); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java new file mode 100644 index 00000000..a89782f9 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/StopVolumeAction.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Display; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; + +public class StopVolumeAction extends AbstractActionDelegate { + private Volume volume; + private GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + + @Override + public void run(IAction action) { + if(volume.getStatus() == VOLUME_STATUS.OFFLINE) { + return; // Volume already offline. Don't do anything. + } + + VolumesClient client = new VolumesClient(modelManager.getSecurityToken()); + final Status status = client.stopVolume(volume.getName()); + final String actionDesc = action.getDescription(); + final Display display = Display.getDefault(); + + display.asyncExec(new Runnable() { + + @Override + public void run() { + if (status.isSuccess()) { + new MessageDialog(Display.getCurrent().getActiveShell(), actionDesc, null, "Volume [" + + volume.getName() + "] stopped successfully!", MessageDialog.INFORMATION, new String[] { "OK" }, 0) + .open(); + modelManager.updateVolumeStatus(volume, VOLUME_STATUS.OFFLINE); + } else { + new MessageDialog(Display.getCurrent().getActiveShell(), actionDesc, null, "Volume [" + + volume.getName() + "] could not be stopped! Error: [" + status + "]", MessageDialog.ERROR, + new String[] { "OK" }, 0).open(); + } + } + }); + } + + @Override + public void dispose() { + } + + /* (non-Javadoc) + * @see com.gluster.storage.management.gui.actions.AbstractActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) + */ + @Override + public void selectionChanged(IAction action, ISelection selection) { + super.selectionChanged(action, selection); + + if (selectedEntity instanceof Volume) { + volume = (Volume) selectedEntity; + action.setEnabled(volume.getStatus() == VOLUME_STATUS.ONLINE); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/TestPopupMenuAction.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/TestPopupMenuAction.java new file mode 100644 index 00000000..e1fe0f14 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/actions/TestPopupMenuAction.java @@ -0,0 +1,62 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.actions; + +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IObjectActionDelegate; +import org.eclipse.ui.IWorkbenchPart; + +public class TestPopupMenuAction implements IObjectActionDelegate { + + private Shell shell; + + /** + * Constructor for Action1. + */ + public TestPopupMenuAction() { + super(); + } + + /** + * @see IObjectActionDelegate#setActivePart(IAction, IWorkbenchPart) + */ + public void setActivePart(IAction action, IWorkbenchPart targetPart) { + shell = targetPart.getSite().getShell(); + } + + /** + * @see IActionDelegate#run(IAction) + */ + public void run(IAction action) { + MessageDialog.openInformation( + shell, + "glustersp-gui", + "New Action was executed."); + } + + /** + * @see IActionDelegate#selectionChanged(IAction, ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java new file mode 100644 index 00000000..80811226 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeDisksPage.java @@ -0,0 +1,306 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +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.Label; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.TableLabelProviderAdapter; +import com.gluster.storage.management.gui.utils.EntityViewerFilter; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.richclientgui.toolbox.duallists.CustomTableDualListComposite; +import com.richclientgui.toolbox.duallists.DualListComposite.ListContentChangedListener; +import com.richclientgui.toolbox.duallists.IRemovableContentProvider; +import com.richclientgui.toolbox.duallists.RemovableContentProvider; +import com.richclientgui.toolbox.duallists.TableColumnData; + +public class CreateVolumeDisksPage extends Composite { + private enum DISK_TABLE_COLUMN_INDICES { + SERVER, DISK, SPACE, SPACE_USED + } + + private static final String[] DISK_TABLE_COLUMNS_NAMES = { "Server", "Disk", "Space (GB)", "Used Space (GB)" }; + + private GUIHelper guiHelper = GUIHelper.getInstance(); + private CustomTableDualListComposite<Disk> dualTableViewer; + private Text filterText; + // This list keeps track of the order of the disks as user changes the same by clicking on up/down arrow buttons + private List<Disk> chosenDisks = new ArrayList<Disk>(); + + private IRemovableContentProvider<Disk> chosenDisksContentProvider; + + private Button btnUp; + + private Button btnDown; + + public CreateVolumeDisksPage(final Composite parent, int style, List<Disk> allDisks, List<Disk> selectedDisks) { + super(parent, style); + + createPage(allDisks, selectedDisks); + + parent.layout(); + } + + private TableLabelProviderAdapter getDiskLabelProvider() { + return new TableLabelProviderAdapter() { + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Disk)) { + return null; + } + + Disk disk = (Disk) element; + return (columnIndex == DISK_TABLE_COLUMN_INDICES.SERVER.ordinal() ? disk.getServerName() + : columnIndex == DISK_TABLE_COLUMN_INDICES.DISK.ordinal() ? disk.getName() + : columnIndex == DISK_TABLE_COLUMN_INDICES.SPACE.ordinal() ? NumberUtil + .formatNumber(disk.getSpace()) + : columnIndex == DISK_TABLE_COLUMN_INDICES.SPACE_USED.ordinal() ? NumberUtil + .formatNumber(disk.getSpaceInUse()) : "Invalid"); + } + }; + } + + private int indexOf(List<Disk> disks, Disk searchDisk) { + for(Disk disk : disks) { + if(disk.getQualifiedName().equals(searchDisk.getQualifiedName())) { + return disks.indexOf(disk); + } + } + return -1; + } + + private void createPage(List<Disk> allDisks, List<Disk> selectedDisks) { + setupPageLayout(); + + filterText = guiHelper.createFilterText(this); + new Label(this, SWT.NONE); + + createDualTableViewer(allDisks, selectedDisks); + createFilter(filterText, false); // attach filter text to the dual table viewer for auto-filtering + + Composite buttonContainer = new Composite(this, SWT.NONE); + buttonContainer.setLayout(new GridLayout(1, false)); + GridData buttonContainerData = new GridData(SWT.FILL, SWT.CENTER, true, true); + buttonContainerData.minimumWidth = 40; + buttonContainer.setLayoutData(buttonContainerData); + + btnUp = new Button(buttonContainer, SWT.TOGGLE); + GridData btnUpData = new GridData(SWT.LEFT, SWT.BOTTOM, true, false); + btnUpData.minimumWidth = 30; + btnUp.setLayoutData(btnUpData); + btnUp.setImage(guiHelper.getImage(IImageKeys.ARROW_UP)); + btnUp.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + chosenDisks = getChosenDisks(); + List<Disk> selectedDisks = getSelectedChosenDisks(); + + chosenDisksContentProvider.removeElements(chosenDisks); + for(Disk disk : selectedDisks) { + int index = chosenDisks.indexOf(disk); + Disk diskAbove = chosenDisks.get(index - 1); + chosenDisks.set(index - 1, disk); + chosenDisks.set(index, diskAbove); + } + chosenDisksContentProvider.addElements(chosenDisks); + dualTableViewer.refreshChosenViewer(); + updateButtons(); + } + }); + + btnDown = new Button(buttonContainer, SWT.TOGGLE); + btnDown.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); + btnDown.setImage(guiHelper.getImage(IImageKeys.ARROW_DOWN)); + btnDown.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + + chosenDisks = getChosenDisks(); + List<Disk> selectedDisks = getSelectedChosenDisks(); + + chosenDisksContentProvider.removeElements(chosenDisks); + for(Disk disk : selectedDisks) { + int index = chosenDisks.indexOf(disk); + Disk diskBelow = chosenDisks.get(index + 1); + chosenDisks.set(index + 1, disk); + chosenDisks.set(index, diskBelow); + } + chosenDisksContentProvider.addElements(chosenDisks); + dualTableViewer.refreshChosenViewer(); + updateButtons(); + + } + }); + } + + private List<Disk> getSelectedChosenDisks() { + TableItem[] selectedItems = dualTableViewer.getChosenTable().getSelection(); + List<Disk> selectedDisks = new ArrayList<Disk>(); + for (TableItem item : selectedItems) { + selectedDisks.add((Disk)item.getData()); + } + return selectedDisks; + } + + private void createFilter(final Text filterText, boolean caseSensitive) { + final String initialFilterString = filterText.getText(); + + final EntityViewerFilter filter = new EntityViewerFilter(initialFilterString, caseSensitive); + // On every keystroke inside the text field, update the filter string + filterText.addKeyListener(new KeyAdapter() { + private String filterString = initialFilterString; + + @Override + public void keyReleased(KeyEvent e) { + String enteredString = filterText.getText(); + if (enteredString.equals(filterString)) { + // Filter string has not changed. don't do anything + return; + } + + // Update filter string + filterString = enteredString; + filter.setFilterString(filterString); + + // Refresh viewer with newly filtered content + dualTableViewer.refreshAvailableViewer(); + dualTableViewer.refreshChosenViewer(); + } + }); + + dualTableViewer.setAvailableViewerFilter(filter); + dualTableViewer.setChosenViewerFilter(filter); + } + + private void createDualTableViewer(List<Disk> allDisks, List<Disk> selectedDisks) { + TableColumnData[] columnData = createColumnData(); + ITableLabelProvider diskLabelProvider = getDiskLabelProvider(); + + dualTableViewer = new CustomTableDualListComposite<Disk>(this, SWT.NONE, columnData, columnData); + + dualTableViewer.setViewerLabels("Available:", "Chosen:"); + + dualTableViewer.setAvailableTableLinesVisible(false); + dualTableViewer.setAvailableTableHeaderVisible(true); + dualTableViewer.setAvailableContentProvider(new RemovableContentProvider<Disk>(getAvailableDisks(allDisks, + selectedDisks))); + dualTableViewer.setAvailableLabelProvider(diskLabelProvider); + + dualTableViewer.setChosenTableLinesVisible(true); + dualTableViewer.setChosenTableHeaderVisible(true); + + chosenDisksContentProvider = new RemovableContentProvider<Disk>(selectedDisks); + dualTableViewer.setChosenContentProvider(chosenDisksContentProvider); + dualTableViewer.setChosenLabelProvider(diskLabelProvider); + + dualTableViewer.getChosenTable().addSelectionListener(new SelectionAdapter() { + /* (non-Javadoc) + * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) + */ + @Override + public void widgetSelected(SelectionEvent e) { + updateButtons(); + } + }); + } + + private void updateButtons() { + btnUp.setEnabled(true); + btnDown.setEnabled(true); + List<Disk> selectedChosenDisks = getSelectedChosenDisks(); + List<Disk> chosenDisks = getChosenDisks(); + for(Disk disk : selectedChosenDisks) { + int index = chosenDisks.indexOf(disk); + if(index == 0) { + btnUp.setEnabled(false); + } + if(index == chosenDisks.size() - 1) { + btnDown.setEnabled(false); + } + } + } + + /** + * @param allDisks + * @param selectedDisks + * @return + */ + private List<Disk> getAvailableDisks(List<Disk> allDisks, List<Disk> selectedDisks) { + List<Disk> availableDisks = new ArrayList<Disk>(); + for (Disk disk : allDisks) { + if (!selectedDisks.contains(disk)) { + availableDisks.add(disk); + } + } + return availableDisks; + } + + private TableColumnData[] createColumnData() { + DISK_TABLE_COLUMN_INDICES[] columns = DISK_TABLE_COLUMN_INDICES.values(); + TableColumnData[] columnData = new TableColumnData[columns.length]; + + for (DISK_TABLE_COLUMN_INDICES column : columns) { + int columnNum = column.ordinal(); + columnData[columnNum] = new TableColumnData(columnNum, DISK_TABLE_COLUMNS_NAMES[columnNum], 100); + } + return columnData; + } + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(2, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + + public List<Disk> getChosenDisks() { + Object[] disksArr = (Object[]) chosenDisksContentProvider.getElements(dualTableViewer); + if (disksArr != null) { + List<Disk> disks = new ArrayList<Disk>(); + for (Object disk : disksArr) { + disks.add((Disk) disk); + } + return disks; + } + return null; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java new file mode 100644 index 00000000..d919fd84 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumePage1.java @@ -0,0 +1,288 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ComboViewer; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.window.Window; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Text; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.NAS_PROTOCOL; +import com.gluster.storage.management.core.model.Volume.TRANSPORT_TYPE; +import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; + +public class CreateVolumePage1 extends WizardPage { + public static final String PAGE_NAME = "create.volume.page.1"; + private Text txtName; + private ComboViewer typeComboViewer; + private Text txtAccessControl; + private Volume volume = new Volume(); + private List<Disk> allDisks; + private Button btnNfs; + private Button btnStartVolume; + private Link linkCustomize; + private ValidationListener valListener = new ValidationListener(); + + /** + * Create the wizard. + */ + public CreateVolumePage1() { + super(PAGE_NAME); + setTitle("Create Volume"); + setDescription("Create a new Volume by choosing disks from the cluster servers and configuring the volume properties."); + + // by default, we create volume with all available disks + allDisks = GlusterDataModelManager.getInstance().getReadyDisksOfAllServers(); + volume.setDisks(allDisks); + } + + private class ValidationListener implements ModifyListener { + /* (non-Javadoc) + * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent) + */ + @Override + public void modifyText(ModifyEvent e) { + String volumeName = txtName.getText().trim(); + String accessControl = txtAccessControl.getText().trim(); + String volumeNameToken = "^[a-zA-Z][a-zA-Z0-9\\-]*"; + + + setErrorMessage(null); + setPageComplete(true); + + if(volumeName.length() == 0) { + setPageComplete(false); + setErrorMessage("Please enter Volume Name"); + } + + if (!volumeName.matches(volumeNameToken)) { + setPageComplete(false); + setErrorMessage("Please enter valid Volume Name"); + } + + if(accessControl.length() == 0) { + setPageComplete(false); + setErrorMessage("Please enter Access Control"); + } + + + // acl validation + String[] aclList = accessControl.split(","); + for (String ip : aclList) { + if (!isValidIP(ip)) { + setPageComplete(false); + setErrorMessage("Please enter valid access control list"); + } + } + + } + + private Boolean isValidIP(String ip) { + // String pattern = "^.[0-9]{1,3}/..[0-9]{1,3}/..[0-9]{1,3}/..[0-9]{1,3}"; + String pattern = "^.[0-9]{1,3}/."; + if (ip == "*") { + return true; + } + String[] ipQuads = ip.split("."); + for (String quad : ipQuads) { + if (!quad.matches(pattern)) { + return false; + } + } + return true; + + } + } + + /** + * Create contents of the wizard. + * @param parent + */ + public void createControl(Composite parent) { + + setPageComplete(false); + Composite container = new Composite(parent, SWT.NULL); + + setControl(container); + GridLayout gl_container = new GridLayout(2, false); + gl_container.verticalSpacing = 10; + gl_container.marginHeight = 10; + gl_container.marginLeft = 20; + gl_container.horizontalSpacing = 10; + container.setLayout(gl_container); + + new Label(container, SWT.NONE); + new Label(container, SWT.NONE); + + Label lblName = new Label(container, SWT.NONE); + lblName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblName.setText("Name: "); + + txtName = new Text(container, SWT.BORDER); + GridData txtNameData = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); + txtNameData.widthHint = 300; + txtName.setLayoutData(txtNameData); + txtName.addModifyListener(valListener); + + Label lblType = new Label(container, SWT.NONE); + lblType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblType.setText("Type: "); + + typeComboViewer = new ComboViewer(container, SWT.READ_ONLY); + Combo typeCombo = typeComboViewer.getCombo(); + GridData typeComboData = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); + typeCombo.setLayoutData(typeComboData); + typeComboViewer.setContentProvider(new ArrayContentProvider()); + typeComboViewer.setInput(Volume.VOLUME_TYPE.values()); + typeCombo.select(VOLUME_TYPE.PLAIN_DISTRIBUTE.ordinal()); // default type = Plain Distribute + typeComboViewer.setLabelProvider(new LabelProvider() { + @Override + public String getText(Object element) { + VOLUME_TYPE volumeType = (VOLUME_TYPE)element; + return Volume.getVolumeTypeStr(volumeType); + } + }); + + Label lblTransportType = new Label(container, SWT.NONE); + lblTransportType.setText("Transport Type: "); + + Label lblEthernet = new Label(container, SWT.NONE); + lblEthernet.setText("Ethernet"); + + Label lblDisks = new Label(container, SWT.RIGHT); + lblDisks.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblDisks.setText("Disks: "); + + linkCustomize = new Link(container, SWT.UNDERLINE_LINK); + linkCustomize.setText("All Disk(s) (<a>customize</a>)"); + linkCustomize.addListener (SWT.Selection, new Listener () { + public void handleEvent(Event event) { + Display.getDefault().asyncExec(new Runnable() { + + @Override + public void run() { + SelectDisksDialog dialog = new SelectDisksDialog(getShell(), allDisks, volume.getDisks()); + + dialog.create(); + if(dialog.open() == Window.OK) { + // user has customized disks. get them from the dialog box. + volume.setDisks(dialog.getSelectedDisks()); + linkCustomize.setText("" + volume.getDisks().size() + " Disk(s) (<a>customize</a>)"); + } + } + }); + } + }); + + Label lblNasProtocol = new Label(container, SWT.RIGHT); + lblNasProtocol.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblNasProtocol.setText("NAS Protocol: "); + + Button btnGluster = new Button(container, SWT.CHECK); + btnGluster.setEnabled(false); + btnGluster.setSelection(true); + btnGluster.setText("Gluster"); + new Label(container, SWT.NONE); + + btnNfs = new Button(container, SWT.CHECK); + btnNfs.setSelection(true); + btnNfs.setText("NFS"); + + Label lblAccessControl = new Label(container, SWT.NONE); + lblAccessControl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblAccessControl.setText("Access Control: "); + + txtAccessControl = new Text(container, SWT.BORDER); + txtAccessControl.setText("*"); + GridData accessControlData = new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1); + accessControlData.widthHint = 300; + txtAccessControl.setLayoutData(accessControlData); + txtAccessControl.addModifyListener(valListener); + + new Label(container, SWT.NONE); + Label lblAccessControlInfo = new Label(container, SWT.TOP); + lblAccessControlInfo.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); + lblAccessControlInfo.setText("(Comma separated list of IP addresses)"); + + Label lblStartVolume = new Label(container, SWT.NONE); + lblStartVolume.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + lblStartVolume.setText("Start Volume: "); + + btnStartVolume = new Button(container, SWT.CHECK); + btnStartVolume.setSelection(true); + } + + public Volume getVolume() { + volume.setName(txtName.getText()); + + IStructuredSelection selection = (IStructuredSelection)typeComboViewer.getSelection(); + volume.setVolumeType((VOLUME_TYPE)selection.getFirstElement()); + + volume.setTransportType(TRANSPORT_TYPE.ETHERNET); + Set<NAS_PROTOCOL> nasProtocols = new HashSet<Volume.NAS_PROTOCOL>(); + nasProtocols.add(NAS_PROTOCOL.GLUSTERFS); + if(btnNfs.getSelection()) { + nasProtocols.add(NAS_PROTOCOL.NFS); + } + + volume.setAccessControlList(txtAccessControl.getText()); + + return volume; + } + + public Boolean getStartVolumeRequest() { + return btnStartVolume.getSelection(); + } + + public Boolean isValidCreateVolumeForm() { + IStructuredSelection selection = (IStructuredSelection)typeComboViewer.getSelection(); + if (selection.getFirstElement().equals(VOLUME_TYPE.DISTRIBUTED_MIRROR) && ((int)volume.getDisks().size()) % 2 != 0 ) { + setErrorMessage("Mirror type volume requires disk in multiples of two"); + return false; + } else if(selection.getFirstElement().equals(VOLUME_TYPE.DISTRIBUTED_STRIPE) && ((int)volume.getDisks().size()) % 4 != 0) { + setErrorMessage("Stripe type volume requires disk in multiples of four"); + return false; + } + return true; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java new file mode 100644 index 00000000..36755bec --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/CreateVolumeWizard.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.wizard.Wizard; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.VolumesClient; +import com.gluster.storage.management.core.model.Status; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; + +public class CreateVolumeWizard extends Wizard { + + public CreateVolumeWizard() { + setWindowTitle("Gluster Management Console - Create Volume"); + setHelpAvailable(false); // TODO: Introduce wizard help + } + + @Override + public void addPages() { + addPage(new CreateVolumePage1()); + } + + @Override + public boolean performFinish() { + CreateVolumePage1 page = (CreateVolumePage1) getPage(CreateVolumePage1.PAGE_NAME); + if (!page.isValidCreateVolumeForm()) { + return false; + } + + Volume newVolume = page.getVolume(); + GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + VolumesClient volumesClient = new VolumesClient(modelManager.getSecurityToken()); + Status status = volumesClient.createVolume(newVolume); + + if (status.isSuccess()) { + newVolume.setStatus(VOLUME_STATUS.OFFLINE); + if (page.getStartVolumeRequest()) { + Status volumeStartStatus = volumesClient.startVolume(newVolume.getName()); + if (volumeStartStatus.isSuccess()) { + newVolume.setStatus(VOLUME_STATUS.ONLINE); + } + } + //update the model + modelManager.addVolume(newVolume); + MessageDialog.openInformation(getShell(), "Create Volume", "Volume created successfully and configuration added!"); + } else { + MessageDialog.openError(getShell(), "Create Volume", "Volume creation failed! [" + status.getCode() + "][" + + status.getMessage() + "]"); + } + + return true; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java new file mode 100644 index 00000000..7dc0b03d --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskPage1.java @@ -0,0 +1,203 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import java.util.List; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +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 com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.GlusterDummyModel; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.TableLabelProviderAdapter; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class MigrateDiskPage1 extends WizardPage { + private static final String PAGE_NAME = "migrate.disk.page.1"; + private enum DISK_TABLE_COLUMN_INDICES { + SERVER, DISK, SPACE, SPACE_IN_USE + } + private static final String[] DISK_TABLE_COLUMN_NAMES = { "Server", "Disk", "Space (GB)", "Used Space (GB)" }; + + private Volume volume; + private Disk fromDisk; + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + private ITableLabelProvider getDiskLabelProvider() { + return new TableLabelProviderAdapter() { + + @Override + public String getColumnText(Object element, int columnIndex) { + if (!(element instanceof Disk)) { + return null; + } + + Disk disk = (Disk) element; + return (columnIndex == DISK_TABLE_COLUMN_INDICES.SERVER.ordinal() ? disk.getServerName() + : columnIndex == DISK_TABLE_COLUMN_INDICES.DISK.ordinal() ? disk.getName() + : columnIndex == DISK_TABLE_COLUMN_INDICES.SPACE.ordinal() ? NumberUtil.formatNumber(disk.getSpace()) + : columnIndex == DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE.ordinal() ? NumberUtil.formatNumber(disk.getSpaceInUse()) + : "Invalid"); + } + }; + } + + private void setupDiskTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, DISK_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SERVER, SWT.CENTER, 100); + setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.DISK, SWT.CENTER, 100); + setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SPACE, SWT.CENTER, 90); + setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE, SWT.CENTER, 90); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, DISK_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } + + + /** + * Create the wizard. + */ + public MigrateDiskPage1(Volume volume, Disk disk) { + super(PAGE_NAME); + this.volume = volume; + this.fromDisk = disk; + setTitle("Migrate Disk [" + volume.getName() + "]"); +// setDescription("Migrate data from one disk to another for the chosen Volume. " + +// "This will copy all data present in the \"from disk\" of the volume " + +// "to \"to disk\", remove \"from disk\" from the volume, and " + +// "add \"to disk\" to the volume"); + setDescription("Migrate volume data from \"From Disk\" to \"To Disk\""); + } + + private void setupPageLayout(Composite container) { + final GridLayout layout = new GridLayout(2, false); + layout.verticalSpacing = 10; + layout.horizontalSpacing = 10; + layout.marginTop = 10; + layout.marginLeft = 10; + layout.marginRight = 10; + container.setLayout(layout); + } + + private Composite createTableViewerComposite(Composite parent) { + Composite tableViewerComposite = new Composite(parent, SWT.NONE); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return tableViewerComposite; + } + + /** + * Create contents of the wizard. + * + * @param parent + */ + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + setControl(container); + + setupPageLayout(container); + + GridData labelLayoutData = new GridData(SWT.LEFT, SWT.BOTTOM, true, false); + labelLayoutData.minimumWidth = 100; + labelLayoutData.verticalAlignment = SWT.BOTTOM; + //labelLayoutData.verticalIndent = 10; + + Label lblFromDisk = new Label(container, SWT.NONE); + lblFromDisk.setText("From Disk:"); + lblFromDisk.setLayoutData(labelLayoutData); + Label lblToDisk = new Label(container, SWT.NONE); + lblToDisk.setText("To Disk:"); + lblToDisk.setLayoutData(labelLayoutData); + + Text txtFilterFrom = guiHelper.createFilterText(container); + Text txtFilterTo = guiHelper.createFilterText(container); + + ITableLabelProvider diskLabelProvider = getDiskLabelProvider(); + + GlusterDummyModel glusterDummyModel = GlusterDummyModel.getInstance(); + List<Disk> fromDisks = glusterDummyModel.getReadyDisksOfVolume(volume); + List<Disk> toDisks = glusterDummyModel.getReadyDisksOfAllServersExcluding(volume.getDisks()); + + TableViewer tableViewerFrom = createTableViewer(container, diskLabelProvider, fromDisks, txtFilterFrom); + if(fromDisk != null) { + setFromDisk(tableViewerFrom, fromDisk); + } + + createTableViewer(container, diskLabelProvider, toDisks, txtFilterTo); + } + + private void setFromDisk(TableViewer tableViewer, Disk diskToSelect) { + Table table = tableViewer.getTable(); + for(int i = 0 ; i < table.getItemCount(); i++) { + TableItem item = table.getItem(i); + if(item.getData() == diskToSelect) { + table.select(i); + return; + } + } + } + + private TableViewer createTableViewer(Composite container, ITableLabelProvider diskLabelProvider, List<Disk> fromDisks, Text txtFilterText) { + Composite tableViewerComposite = createTableViewerComposite(container); + + TableViewer tableViewer = new TableViewer(tableViewerComposite, SWT.SINGLE); + tableViewer.setContentProvider(new ArrayContentProvider()); + tableViewer.setLabelProvider(diskLabelProvider); + + setupDiskTable(tableViewerComposite, tableViewer.getTable()); + guiHelper.createFilter(tableViewer, txtFilterText, false); + + tableViewer.setInput(fromDisks.toArray()); + return tableViewer; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java new file mode 100644 index 00000000..464abefa --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/MigrateDiskWizard.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import org.eclipse.jface.wizard.Wizard; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Volume; + +public class MigrateDiskWizard extends Wizard { + private Volume volume; + private Disk disk; + + public MigrateDiskWizard(Volume volume, Disk disk) { + setWindowTitle("Gluster Management Console - Migrate Disk [" + volume.getName() + "]"); + this.volume = volume; + this.disk = disk; + setHelpAvailable(false); // TODO: Introduce wizard help + } + + @Override + public void addPages() { + addPage(new MigrateDiskPage1(volume, disk)); + } + + @Override + public boolean performFinish() { + System.out.println("Triggered Disk Migration!"); + // TODO: Add code to migrate disk + return true; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java new file mode 100644 index 00000000..10a36fb0 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/dialogs/SelectDisksDialog.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.dialogs; + +import java.util.List; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.osgi.framework.internal.core.Msg; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Volume; + +public class SelectDisksDialog extends Dialog { + + private CreateVolumeDisksPage disksPage; + private List<Disk> allDisks; + private List<Disk> selectedDisks; + + /** + * Create the dialog. + * + * @param parentShell + */ + public SelectDisksDialog(Shell parentShell, List<Disk> allDisks, List<Disk> selectedDisks) { + super(parentShell); + setShellStyle(getShellStyle() | SWT.RESIZE); + this.allDisks = allDisks; + this.selectedDisks = selectedDisks; + } + + /** + * Create contents of the dialog. + * + * @param parent + */ + @Override + protected Control createDialogArea(Composite parent) { + Composite container = new Composite(parent, SWT.NONE); + GridLayout containerLayout = new GridLayout(2, false); + container.setLayout(containerLayout); + GridData containerLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + container.setLayoutData(containerLayoutData); + + getShell().setText("Create Volume - Select Disks"); + + disksPage = new CreateVolumeDisksPage(container, SWT.NONE, allDisks, selectedDisks); + + return container; + } + + /** + * Create contents of the button bar. + * + * @param parent + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + } + + /** + * Return the initial size of the dialog. + */ + @Override + protected Point getInitialSize() { + return new Point(1024, 600); + } + + @Override + protected void cancelPressed() { + super.cancelPressed(); + } + + @Override + protected void okPressed() { + if (this.getSelectedDisks().size() == 0 ) { + MessageDialog.openError(getShell(), "Select Disk(s)", "Please select atlease one disk"); + } else { + super.okPressed(); + } + } + + public List<Disk> getSelectedDisks() { + return disksPage.getChosenDisks(); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java new file mode 100644 index 00000000..b5945e61 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/jobs/InitializeDiskJob.java @@ -0,0 +1,84 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.jobs; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ui.progress.IProgressConstants; +import org.eclipse.ui.progress.IProgressConstants2; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.gui.Application; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class InitializeDiskJob extends Job { + private Disk disk; + private Application app = Application.getApplication(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + public InitializeDiskJob(Disk disk) { + super("Initialize Disk [" + disk.getQualifiedName() + "]"); + this.disk = disk; + setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE); + setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); + setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.WORK_IN_PROGRESS)); + } + + private void updateStatus(final DISK_STATUS status) { + disk.setStatus(status); + disk.setSpaceInUse(0d); + app.entityChanged(disk, new String[] { "status", "spaceInUse" }); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask("Formatting the disk...", 100); + boolean cancelRequested = false; + String msgPrefix = ""; + try { + for (int i = 1; i <= 5; i++) { + if (!cancelRequested && monitor.isCanceled()) { + cancelRequested = true; // come only once here + + msgPrefix = "This task cannot be cancelled! "; + monitor.setTaskName(msgPrefix); +// setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.STATUS_CANCELLED)); +// +// updateStatus(DISK_STATUS.UNINITIALIZED); +// return new Status(Status.CANCEL, Application.PLUGIN_ID, "Cancelled"); + } + Thread.sleep(2000); + monitor.worked(20); + monitor.setTaskName(msgPrefix + "[" + 20 * i + "%] completed"); + } + monitor.done(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + updateStatus(DISK_STATUS.READY); + setProperty(IProgressConstants.ICON_PROPERTY, guiHelper.getImageDescriptor(IImageKeys.STATUS_SUCCESS)); + + return new Status(Status.OK, Application.PLUGIN_ID, "Task Completed!"); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/login/LoginDialog.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/login/LoginDialog.java new file mode 100644 index 00000000..45b13a19 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/login/LoginDialog.java @@ -0,0 +1,200 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.login; + +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.UpdateValueStrategy; +import org.eclipse.core.databinding.beans.PojoProperties; +import org.eclipse.jface.databinding.swt.SWTObservables; +import org.eclipse.jface.databinding.swt.WidgetProperties; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.TraverseEvent; +import org.eclipse.swt.events.TraverseListener; +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.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.client.UsersClient; +import com.gluster.storage.management.client.constants.ClientConstants; +import com.gluster.storage.management.core.model.ConnectionDetails; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.validators.StringRequiredValidator; + +/** + * Login dialog, which prompts for the user's account info, and has Login and Cancel buttons. + */ +public class LoginDialog extends Dialog { + + private Text userIdText = null; + private Text passwordText = null; + private Button okButton; + + private final ConnectionDetails connectionDetails = new ConnectionDetails("gluster", ""); + private final GUIHelper guiHelper = GUIHelper.getInstance(); + private Composite composite; + + public LoginDialog(Shell parentShell) { + super(parentShell); + } + + + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + + newShell.setText("Gluster Management Console"); + addEscapeListener(newShell); + } + + private void addEscapeListener(Shell shell) { + shell.addTraverseListener(new TraverseListener() { + + @Override + public void keyTraversed(TraverseEvent e) { + if (e.keyCode == SWT.ESC) { + cancelPressed(); + } + } + }); + } + + private void createUserIdLabel(Composite composite) { + Label userIdLabel = new Label(composite, SWT.NONE); + userIdLabel.setText("&User ID:"); + userIdLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private void createUserIdText(Composite composite) { + userIdText = new Text(composite, SWT.BORDER); + userIdText.setText("gluster"); + userIdText.setEnabled(false); + + GridData layoutData = new GridData(SWT.FILL, GridData.FILL, true, false); + ; + layoutData.widthHint = convertWidthInCharsToPixels(32); + userIdText.setLayoutData(layoutData); + } + + private void createPasswordLabel(Composite composite) { + Label passwordLabel = new Label(composite, SWT.NONE); + passwordLabel.setText("&Password:"); + passwordLabel.setLayoutData(new GridData(GridData.END, GridData.CENTER, false, false)); + } + + private void createPasswordText(Composite composite) { + passwordText = new Text(composite, SWT.BORDER | SWT.PASSWORD); + + GridData layoutData = new GridData(SWT.FILL, GridData.FILL, true, false); + ; + layoutData.widthHint = convertWidthInCharsToPixels(32); + passwordText.setLayoutData(layoutData); + } + + private void configureDialogLayout(Composite composite) { + GridLayout layout = (GridLayout) composite.getLayout(); + layout.numColumns = 2; + layout.marginLeft = 20; + layout.marginRight = 20; + layout.marginTop = 20; + layout.horizontalSpacing = 20; + layout.verticalSpacing = 20; + } + + /** + * Overriding to make sure that the dialog is centered in screen + */ + @Override + protected void initializeBounds() { + super.initializeBounds(); + + guiHelper.centerShellInScreen(getShell()); + } + + @Override + protected Control createDialogArea(Composite parent) { + parent.setBackgroundImage(guiHelper.getImage(IImageKeys.DIALOG_SPLASH_IMAGE)); + parent.setBackgroundMode(SWT.INHERIT_FORCE); // Makes sure that child composites inherit the same background + + composite = (Composite) super.createDialogArea(parent); + configureDialogLayout(composite); + + createUserIdLabel(composite); + createUserIdText(composite); + + createPasswordLabel(composite); + createPasswordText(composite); + + return composite; + } + + @Override + protected void createButtonsForButtonBar(Composite parent) { + okButton = createButton(parent, IDialogConstants.OK_ID, "&Login", true); + createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); + + setupDataBinding(); + } + + /** + * Sets up data binding between the text fields and the connection details object. Also attaches a "string required" + * validator to the "password" text field. This validator is configured to do the following on validation failure<br> + * <li>show an ERROR decorator</li><li>disable the "Login" button + */ + private void setupDataBinding() { + DataBindingContext dataBindingContext = new DataBindingContext(SWTObservables.getRealm(Display.getCurrent())); + UpdateValueStrategy passwordBindingStrategy = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); + + // The Validator shows error decoration and disables OK button on validation failure + passwordBindingStrategy.setBeforeSetValidator(new StringRequiredValidator("Please enter password!", guiHelper + .createErrorDecoration(passwordText), okButton)); + + dataBindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(passwordText), + PojoProperties.value("password").observe(connectionDetails), passwordBindingStrategy, + passwordBindingStrategy); + + UpdateValueStrategy userIdBindingStrategy = new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE); + dataBindingContext + .bindValue(WidgetProperties.text(SWT.Modify).observe(userIdText), PojoProperties.value("userId") + .observe(connectionDetails), userIdBindingStrategy, userIdBindingStrategy); + } + + protected void okPressed() { + String user = connectionDetails.getUserId(); + String password = connectionDetails.getPassword(); + + UsersClient usersClient = new UsersClient(); + if (usersClient.authenticate(user, password)) { + GlusterDataModelManager.getInstance().initializeModel(usersClient.getSecurityToken()); + super.okPressed(); + } else { + MessageDialog.openError(getShell(), "Authentication Failed", "Invalid User ID or password"); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ClusterPreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ClusterPreferencePage.java new file mode 100644 index 00000000..14dbeba9 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ClusterPreferencePage.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.preferences; + +import org.eclipse.jface.preference.*; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.IWorkbench; + +import com.gluster.storage.management.gui.Activator; + +/** + * This class represents a preference page that + * is contributed to the Preferences dialog. By + * subclassing <samp>FieldEditorPreferencePage</samp>, we + * can use the field support built into JFace that allows + * us to create a page that is small and knows how to + * save, restore and apply itself. + * <p> + * This page is used to modify preferences only. They + * are stored in the preference store that belongs to + * the main plug-in class. That way, preferences can + * be accessed directly via the preference store. + */ + +public class ClusterPreferencePage + extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage { + + public ClusterPreferencePage() { + super(GRID); + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + setDescription("A demonstration of a preference page implementation"); + } + + /** + * Creates the field editors. Field editors are abstractions of + * the common GUI blocks needed to manipulate various types + * of preferences. Each field editor knows how to save and + * restore itself. + */ + public void createFieldEditors() { + addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, + "&Directory preference:", getFieldEditorParent())); + addField( + new BooleanFieldEditor( + PreferenceConstants.P_BOOLEAN, + "&An example of a boolean preference", + getFieldEditorParent())); + + addField(new RadioGroupFieldEditor( + PreferenceConstants.P_CHOICE, + "An example of a multiple-choice preference", + 1, + new String[][] { { "&Choice 1", "choice1" }, { + "C&hoice 2", "choice2" } + }, getFieldEditorParent())); + addField( + new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ConsolePreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ConsolePreferencePage.java new file mode 100644 index 00000000..2d49af9b --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/ConsolePreferencePage.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.preferences; + +import org.eclipse.jface.preference.*; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.IWorkbench; + +import com.gluster.storage.management.gui.Activator; + +/** + * This class represents a preference page that + * is contributed to the Preferences dialog. By + * subclassing <samp>FieldEditorPreferencePage</samp>, we + * can use the field support built into JFace that allows + * us to create a page that is small and knows how to + * save, restore and apply itself. + * <p> + * This page is used to modify preferences only. They + * are stored in the preference store that belongs to + * the main plug-in class. That way, preferences can + * be accessed directly via the preference store. + */ + +public class ConsolePreferencePage + extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage { + + public ConsolePreferencePage() { + super(GRID); + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + setDescription("A demonstration of a preference page implementation"); + } + + /** + * Creates the field editors. Field editors are abstractions of + * the common GUI blocks needed to manipulate various types + * of preferences. Each field editor knows how to save and + * restore itself. + */ + public void createFieldEditors() { + addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, + "&Directory preference:", getFieldEditorParent())); + addField( + new BooleanFieldEditor( + PreferenceConstants.P_BOOLEAN, + "&An example of a boolean preference", + getFieldEditorParent())); + + addField(new RadioGroupFieldEditor( + PreferenceConstants.P_CHOICE, + "An example of a multiple-choice preference", + 1, + new String[][] { { "&Choice 1", "choice1" }, { + "C&hoice 2", "choice2" } + }, getFieldEditorParent())); + addField( + new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java new file mode 100644 index 00000000..23b2cff2 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/GlusterPreferencePage.java @@ -0,0 +1,83 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.preferences; + +import org.eclipse.jface.preference.*; +import org.eclipse.ui.IWorkbenchPreferencePage; +import org.eclipse.ui.IWorkbench; + +import com.gluster.storage.management.gui.Activator; + +/** + * This class represents a preference page that + * is contributed to the Preferences dialog. By + * subclassing <samp>FieldEditorPreferencePage</samp>, we + * can use the field support built into JFace that allows + * us to create a page that is small and knows how to + * save, restore and apply itself. + * <p> + * This page is used to modify preferences only. They + * are stored in the preference store that belongs to + * the main plug-in class. That way, preferences can + * be accessed directly via the preference store. + */ + +public class GlusterPreferencePage + extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage { + + public GlusterPreferencePage() { + super(GRID); + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + setDescription("A demonstration of a preference page implementation"); + } + + /** + * Creates the field editors. Field editors are abstractions of + * the common GUI blocks needed to manipulate various types + * of preferences. Each field editor knows how to save and + * restore itself. + */ + public void createFieldEditors() { + addField(new DirectoryFieldEditor(PreferenceConstants.P_PATH, + "&Directory preference:", getFieldEditorParent())); + addField( + new BooleanFieldEditor( + PreferenceConstants.P_BOOLEAN, + "&An example of a boolean preference", + getFieldEditorParent())); + + addField(new RadioGroupFieldEditor( + PreferenceConstants.P_CHOICE, + "An example of a multiple-choice preference", + 1, + new String[][] { { "&Choice 1", "choice1" }, { + "C&hoice 2", "choice2" } + }, getFieldEditorParent())); + addField( + new StringFieldEditor(PreferenceConstants.P_STRING, "A &text preference:", getFieldEditorParent())); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + public void init(IWorkbench workbench) { + } + +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java new file mode 100644 index 00000000..4c1bfcd5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceConstants.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.preferences; + +/** + * Constant definitions for plug-in preferences + */ +public class PreferenceConstants { + + public static final String P_PATH = "pathPreference"; + + public static final String P_BOOLEAN = "booleanPreference"; + + public static final String P_CHOICE = "choicePreference"; + + public static final String P_STRING = "stringPreference"; + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java new file mode 100644 index 00000000..74ace130 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/preferences/PreferenceInitializer.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.preferences; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.jface.preference.IPreferenceStore; + +import com.gluster.storage.management.gui.Activator; + +/** + * Class used to initialize default preference values. + */ +public class PreferenceInitializer extends AbstractPreferenceInitializer { + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences() + */ + public void initializeDefaultPreferences() { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + store.setDefault(PreferenceConstants.P_BOOLEAN, true); + store.setDefault(PreferenceConstants.P_CHOICE, "choice2"); + store.setDefault(PreferenceConstants.P_STRING, + "Default value"); + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/toolbar/GlusterToolbarManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/toolbar/GlusterToolbarManager.java new file mode 100644 index 00000000..a98c7862 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/toolbar/GlusterToolbarManager.java @@ -0,0 +1,102 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.toolbar; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchWindow; + +import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.actions.IActionSetIDs; + +public class GlusterToolbarManager implements ToolbarManager { + private enum ENTITY_TYPE { + CLUSTER, VOLUMES, VOLUME, GLUSTER_SERVERS, GLUSTER_SERVER, DISCOVERED_SERVERS, DISCOVERED_SERVER + }; + + private IWorkbenchWindow window; + private final Map<Class<? extends Entity>, ENTITY_TYPE> entityTypeMap = createEntityTypeMap(); + private final Map<ENTITY_TYPE, String> actionSetMap = createActionSetMap(); + + private Map<Class<? extends Entity>, ENTITY_TYPE> createEntityTypeMap() { + Map<Class<? extends Entity>, ENTITY_TYPE> entityTypeMap = new HashMap<Class<? extends Entity>, GlusterToolbarManager.ENTITY_TYPE>(); + entityTypeMap.put(Cluster.class, ENTITY_TYPE.CLUSTER); + entityTypeMap.put(Volume.class, ENTITY_TYPE.VOLUME); + entityTypeMap.put(Server.class, ENTITY_TYPE.DISCOVERED_SERVER); + entityTypeMap.put(GlusterServer.class, ENTITY_TYPE.GLUSTER_SERVER); + + return entityTypeMap; + } + + private Map<ENTITY_TYPE, String> createActionSetMap() { + Map<ENTITY_TYPE, String> actionSetMap = new HashMap<GlusterToolbarManager.ENTITY_TYPE, String>(); + actionSetMap.put(ENTITY_TYPE.CLUSTER, IActionSetIDs.ACTION_SET_CLUSTER); + actionSetMap.put(ENTITY_TYPE.VOLUMES, IActionSetIDs.ACTION_SET_VOLUMES); + actionSetMap.put(ENTITY_TYPE.VOLUME, IActionSetIDs.ACTION_SET_VOLUME); + actionSetMap.put(ENTITY_TYPE.GLUSTER_SERVERS, IActionSetIDs.ACTION_SET_GLUSTER_SERVERS); + actionSetMap.put(ENTITY_TYPE.GLUSTER_SERVER, IActionSetIDs.ACTION_SET_GLUSTER_SERVER); + actionSetMap.put(ENTITY_TYPE.DISCOVERED_SERVERS, IActionSetIDs.ACTION_SET_DISCOVERED_SERVERS); + actionSetMap.put(ENTITY_TYPE.DISCOVERED_SERVER, IActionSetIDs.ACTION_SET_DISCOVERED_SERVER); + + return actionSetMap; + } + + public GlusterToolbarManager(IWorkbenchWindow window) { + this.window = window; + } + + @SuppressWarnings("rawtypes") + private ENTITY_TYPE getEntityType(Entity entity) { + if (entity instanceof EntityGroup) { + EntityGroup entityGroup = (EntityGroup) entity; + if (entityGroup.getEntityType() == Volume.class) { + return ENTITY_TYPE.VOLUMES; + } else if (entityGroup.getEntityType() == GlusterServer.class) { + return ENTITY_TYPE.GLUSTER_SERVERS; + } else { + return ENTITY_TYPE.DISCOVERED_SERVERS; + } + } + + return entityTypeMap.get(entity.getClass()); + } + + @Override + public void updateToolbar(Entity entity) { + ENTITY_TYPE entityType = getEntityType(entity); + IWorkbenchPage page = window.getActivePage(); + + for (ENTITY_TYPE targetEntityType : actionSetMap.keySet()) { + String actionSetId = actionSetMap.get(targetEntityType); + if (entityType == targetEntityType) { + // show only the action set mapped to given entity + page.showActionSet(actionSetId); + } else { + page.hideActionSet(actionSetId); + } + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/toolbar/ToolbarManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/toolbar/ToolbarManager.java new file mode 100644 index 00000000..f68346d6 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/toolbar/ToolbarManager.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.toolbar; + +import com.gluster.storage.management.core.model.Entity; + +/** + * Whenever the current selection/action demands changes to the toolbar, the toolbar manager is used to update the + * toolbar. + */ +public interface ToolbarManager { + /** + * Updates the toolbar for given entity. This typically means that user is working with the given entity, and hence + * the toolbar actions related to that entity should be made visible, and other un-related actions should be hidden. + * + * @param entity + */ + public void updateToolbar(Entity entity); +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/EntityViewerFilter.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/EntityViewerFilter.java new file mode 100644 index 00000000..9cbf6664 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/EntityViewerFilter.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.utils; + +import java.util.Map.Entry; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +import com.gluster.storage.management.core.model.Filterable; +import com.gluster.storage.management.core.utils.StringUtil; + +public class EntityViewerFilter extends ViewerFilter { + + private String filterString; + private boolean caseSensitive = false; + + public EntityViewerFilter(String filterString, boolean caseSensitive) { + this.filterString = filterString; + this.caseSensitive = caseSensitive; + } + + public boolean isCaseSensitive() { + return caseSensitive; + } + + public void setCaseSensitive(boolean caseSensitive) { + this.caseSensitive = caseSensitive; + } + + public String getFilterString() { + return filterString; + } + + public void setFilterString(String filterString) { + this.filterString = filterString; + } + + @SuppressWarnings("unchecked") + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + if (filterString == null || filterString.isEmpty()) { + // No filter string. select everything + return true; + } + + if (element instanceof Filterable) { + return ((Filterable) element).filter(filterString, caseSensitive); + } + + if(element instanceof Entry) { + Entry<String, String> entry = (Entry<String, String>)element; + return StringUtil.filterString(entry.getKey() + entry.getValue(), filterString, caseSensitive); + } + + if(element instanceof String) { + return StringUtil.filterString((String)element, filterString, caseSensitive); + } + + return false; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java new file mode 100644 index 00000000..ccd5d8ec --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/GUIHelper.java @@ -0,0 +1,363 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.utils; + +import java.util.Iterator; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.jface.fieldassist.FieldDecorationRegistry; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ColumnLayoutData; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +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.Text; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.forms.events.ExpansionAdapter; +import org.eclipse.ui.forms.events.ExpansionEvent; +import org.eclipse.ui.forms.widgets.ColumnLayout; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.forms.widgets.Section; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.views.NavigationView; + +public class GUIHelper { + private static final GUIHelper instance = new GUIHelper(); + private static final ImageUtil imageUtil = new ImageUtil(); + + private GUIHelper() { + + } + + public static GUIHelper getInstance() { + return instance; + } + + public ScrolledForm setupForm(Composite parent, FormToolkit toolkit, final String formName) { + return setupForm(toolkit, formName, toolkit.createScrolledForm(parent)); + } + + public ScrolledForm setupForm(FormToolkit toolkit, final String formName, ScrolledForm form) { + form.setText(formName); + toolkit.decorateFormHeading(form.getForm()); + + ColumnLayout layout = new ColumnLayout(); + + // layout.topMargin = 0; + // layout.bottomMargin = 5; + // layout.leftMargin = 10; + // layout.rightMargin = 10; + // layout.horizontalSpacing = 10; + // layout.verticalSpacing = 10; + // layout.maxNumColumns = 4; + // layout.minNumColumns = 1; + + form.getBody().setLayout(layout); + return form; + } + + public Composite createSection(final ScrolledForm form, FormToolkit toolkit, String title, String desc, + int numColumns, boolean collapsible) { + int style = Section.TITLE_BAR | Section.EXPANDED; + if (desc != null && !desc.isEmpty()) { + style |= Section.DESCRIPTION; + } + if (collapsible) { + style |= Section.TWISTIE; + } + + Section section = toolkit.createSection(form.getBody(), style); + section.setText(title); + section.setDescription(desc); + + // toolkit.createCompositeSeparator(section); + Composite client = toolkit.createComposite(section); + GridLayout layout = new GridLayout(); + layout.marginWidth = layout.marginHeight = 0; + layout.numColumns = numColumns; + layout.verticalSpacing = 15; + layout.marginBottom = 20; + layout.marginTop = 5; + + client.setLayout(layout); + section.setClient(client); + + section.addExpansionListener(new ExpansionAdapter() { + public void expansionStateChanged(ExpansionEvent e) { + form.reflow(false); + } + }); + return client; + } + + public Composite createTab(TabFolder tabFolder, String title, String imageKey) { + TabItem item = new TabItem(tabFolder, SWT.NONE); + item.setText(title); + item.setImage(getImage(imageKey)); + + Composite composite = new Composite(tabFolder, SWT.NONE); + composite.setLayout(new FillLayout()); + + item.setControl(composite); + + return composite; + } + + public ImageDescriptor getImageDescriptor(String imagePath) { + return imageUtil.getImageDescriptor(imagePath); + } + + public Image getImage(String imagePath) { + return imageUtil.getImage(imagePath); + } + + public Action createPullDownMenu(String menuName, String iconPath, final MenuManager menuManager) { + Action action = new Action(menuName, IAction.AS_DROP_DOWN_MENU) { + public void run() { + } + }; + action.setMenuCreator(new IMenuCreator() { + + @Override + public Menu getMenu(Menu menu) { + return null; + } + + @Override + public Menu getMenu(Control control) { + return menuManager.createContextMenu(control); + } + + @Override + public void dispose() { + } + }); + action.setImageDescriptor(getImageDescriptor(iconPath)); + return action; + } + + public TableColumnLayout createTableColumnLayout(Table table, String[] columns) { + TableColumnLayout tableColumnLayout = new TableColumnLayout(); + ColumnLayoutData defaultColumnLayoutData = new ColumnWeightData(100); + + for (String columnName : columns) { + TableColumn column = new TableColumn(table, SWT.LEFT); + column.setText(columnName); + + tableColumnLayout.setColumnData(column, defaultColumnLayoutData); + } + + return tableColumnLayout; + } + + /** + * Creates a filter for given structured viewer that will filter the contents of the viewer based on the current + * text of the text field + * + * @param viewer + * Structured viewer for which the filter is to be created + * @param filterText + * The text field whose contents are to be used for filtering + * @param caseSensitive + * Flag indicating whether the filtering should be case sensitive + * @return The newly created filter + */ + public EntityViewerFilter createFilter(final StructuredViewer viewer, final Text filterText, boolean caseSensitive) { + final String initialFilterString = filterText.getText(); + + final EntityViewerFilter filter = new EntityViewerFilter(initialFilterString, caseSensitive); + // On every keystroke inside the text field, update the filter string + filterText.addKeyListener(new KeyAdapter() { + private String filterString = initialFilterString; + + @Override + public void keyReleased(KeyEvent e) { + String enteredString = filterText.getText(); + if (enteredString.equals(filterString)) { + // Filter string has not changed. don't do anything + return; + } + + // Update filter string + filterString = enteredString; + filter.setFilterString(filterString); + + // Refresh viewer with newly filtered content + viewer.refresh(true); + } + }); + + viewer.addFilter(filter); + return filter; + } + + public IViewPart getView(String viewId) { + IViewReference[] views = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .getViewReferences(); + for (IViewReference view : views) { + if (view.getId().equals(viewId)) { + return view.getView(false); + } + } + return null; + } + + public ControlDecoration createErrorDecoration(Control control) { + ControlDecoration passwordErrorDecoration = new ControlDecoration(control, SWT.LEFT | SWT.TOP); + passwordErrorDecoration.setImage(FieldDecorationRegistry.getDefault() + .getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage()); + return passwordErrorDecoration; + } + + public void centerShellInScreen(Shell shell) { + Rectangle monitorBounds = shell.getMonitor().getBounds(); + Rectangle myBounds = shell.getBounds(); + + int x = monitorBounds.x + (monitorBounds.width - myBounds.width) / 2; + int y = monitorBounds.y + (monitorBounds.height - myBounds.height) / 2; + shell.setLocation(x, y); + } + + public Text createFilterText(FormToolkit toolkit, Composite parent) { + final String tooltipMessage = "Start typing to filter table contents."; + final Text filterText = toolkit.createText(parent, "", SWT.FLAT); + + GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false); + data.widthHint = 300; + filterText.setLayoutData(data); + + ControlDecoration searchDecoration = new ControlDecoration(filterText, SWT.RIGHT); + searchDecoration.setImage(getImage(IImageKeys.SEARCH)); + searchDecoration.show(); + searchDecoration.setShowHover(true); + searchDecoration.setDescriptionText(tooltipMessage); + + filterText.setToolTipText(tooltipMessage); + return filterText; + } + + public Text createFilterText(Composite parent) { + final String tooltipMessage = "Start typing to filter table contents."; + final Text filterText = new Text(parent, SWT.FLAT); + + GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false); + data.widthHint = 300; + filterText.setLayoutData(data); + + ControlDecoration searchDecoration = new ControlDecoration(filterText, SWT.RIGHT); + searchDecoration.setImage(getImage(IImageKeys.SEARCH)); + searchDecoration.show(); + searchDecoration.setShowHover(true); + searchDecoration.setDescriptionText(tooltipMessage); + + filterText.setToolTipText(tooltipMessage); + return filterText; + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, int columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + * + * @return The table viewer column created + */ + public TableViewerColumn setColumnProperties(TableViewer tableViewer, int columnIndex, int style, int weight) { + TableViewerColumn column = new TableViewerColumn(tableViewer, style, columnIndex); + TableColumnLayout tableColumnLayout = (TableColumnLayout) tableViewer.getTable().getParent().getLayout(); + tableColumnLayout.setColumnData(column.getColumn(), new ColumnWeightData(weight)); + column.setLabelProvider(new ColumnLabelProvider()); + return column; + } + + /** + * Fetches the currently selected objects from the workbench site and returns the one of given type. If none of the + * selected objects are of given type, returns null + * + * @param site + * The workbench site + * @param expectedType + * Type of the selected object to look for + * @return The selected object of given type if found, else null + */ + public Object getSelectedEntity(IWorkbenchSite site, Class expectedType) { + ISelection selection = site.getWorkbenchWindow().getSelectionService().getSelection(NavigationView.ID); + if (selection instanceof IStructuredSelection) { + Iterator<Object> iter = ((IStructuredSelection) selection).iterator(); + while (iter.hasNext()) { + Object selectedObj = iter.next(); + if (selectedObj.getClass() == expectedType) { + return selectedObj; + } + } + } + return null; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ImageUtil.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ImageUtil.java new file mode 100644 index 00000000..efa169de --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/ImageUtil.java @@ -0,0 +1,51 @@ +/** + * ImageUtil.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.utils; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import com.gluster.storage.management.gui.Application; + +/** + * + */ +public class ImageUtil { + private static final LRUCache<String, Image> imageCache = new LRUCache<String, Image>(20); + + public ImageDescriptor getImageDescriptor(String imagePath) { + return AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, imagePath); + } + + public synchronized Image getImage(String imagePath) { + if(imageCache.containsKey(imagePath)) { + return imageCache.get(imagePath); + } + return createImage(imagePath); + } + + private Image createImage(String imagePath) { + Image image = getImageDescriptor(imagePath).createImage(); + imageCache.put(imagePath, image); + return image; + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/LRUCache.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/LRUCache.java new file mode 100644 index 00000000..3c805ac8 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/utils/LRUCache.java @@ -0,0 +1,55 @@ +/** + * LRUCache.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.utils; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * An LRU cache, based on <code>LinkedHashMap</code>. + * <p> + * This cache has a fixed maximum number of elements (<code>cacheSize</code>). If the cache is full and another entry is + * added, the LRU (least recently used) entry is dropped. + * + */ +public class LRUCache<K, V> extends LinkedHashMap<K, V> { + + private static final long serialVersionUID = 1L; + private static final float loadFactor = 0.75f; + private int cacheSize; + + /** + * Creates a new LRU cache. + * + * @param cacheSize + * the maximum number of entries that will be kept in this cache. + */ + public LRUCache(int cacheSize) { + super((int) Math.ceil(cacheSize / loadFactor) + 1, loadFactor, true); + this.cacheSize = cacheSize; + } + + @Override + protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { + return size() > cacheSize; + } + +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java new file mode 100644 index 00000000..fd76c6e5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/validators/StringRequiredValidator.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.validators; + +import org.eclipse.core.databinding.validation.IValidator; +import org.eclipse.core.databinding.validation.ValidationStatus; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.fieldassist.ControlDecoration; +import org.eclipse.swt.widgets.Control; + +public class StringRequiredValidator implements IValidator { + private final String errorText; + private final ControlDecoration controlDecoration; + private final Control linkedControl; + + public StringRequiredValidator(String errorText, ControlDecoration controlDecoration, Control linkedControl) { + super(); + this.errorText = errorText; + this.controlDecoration = controlDecoration; + this.linkedControl = linkedControl; + } + + public StringRequiredValidator(String errorText, ControlDecoration controlDecoration) { + this(errorText, controlDecoration, null); + } + + public IStatus validate(Object value) { + if (value instanceof String) { + if (((String) value).isEmpty()) { + controlDecoration.setDescriptionText(errorText); + controlDecoration.show(); + if (linkedControl != null) { + linkedControl.setEnabled(false); + } + return ValidationStatus.error(errorText); + } + } + linkedControl.setEnabled(true); + controlDecoration.hide(); + return Status.OK_STATUS; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java new file mode 100644 index 00000000..b2d2b93a --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ClusterSummaryView.java @@ -0,0 +1,155 @@ +/** + * DiscoveredServerView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ImageHyperlink; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.tabcreators.PieChartViewerComposite; + +/** + * @author root + * + */ +public class ClusterSummaryView extends ViewPart { + public static final String ID = ClusterSummaryView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private Cluster cluster; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (cluster == null) { + //cluster = (Cluster)guiHelper.getSelectedEntity(getSite(), Cluster.class); + cluster = (Cluster)GlusterDataModelManager.getInstance().getModel().getChildren().get(0); + } + + createSections(parent); + } + + private int getVolumeCountByStatus(Cluster cluster, VOLUME_STATUS status) { + int count = 0; + for (Volume volume : cluster.getVolumes()) { + if (volume.getStatus() == status) { + count++; + } + } + return count; + } + + private int getServerCountByStatus(Cluster cluster, SERVER_STATUS status) { + int count = 0; + for (GlusterServer server : cluster.getServers()) { + if (server.getStatus() == status) { + count++; + } + } + return count; + } + + private void createVolumesSection() { + Composite section = guiHelper.createSection(form, toolkit, "Volumes", null, 1, false); + + Double[] values = new Double[] { Double.valueOf(getVolumeCountByStatus(cluster, VOLUME_STATUS.ONLINE)), + Double.valueOf(getVolumeCountByStatus(cluster, VOLUME_STATUS.OFFLINE)) }; + createStatusChart(toolkit, section, values); + } + + private void createServersSection() { + Composite section = guiHelper.createSection(form, toolkit, "Servers", null, 1, false); + + Double[] values = new Double[] { Double.valueOf(getServerCountByStatus(cluster, SERVER_STATUS.ONLINE)), + Double.valueOf(getServerCountByStatus(cluster, SERVER_STATUS.OFFLINE)) }; + + createStatusChart(toolkit, section, values); + } + + private void createStatusChart(FormToolkit toolkit, Composite section, Double[] values) { + String[] categories = new String[] { "Online", "Offline" }; + PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, values); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = 250; + data.heightHint = 250; + chartViewerComposite.setLayoutData(data); + } + + private void createActionsSection() { + Composite section = guiHelper.createSection(form, toolkit, "Actions", null, 1, false); + + ImageHyperlink imageHyperlink = toolkit.createImageHyperlink(section, SWT.NONE); + imageHyperlink.setText("Create Volume"); + imageHyperlink.setImage(guiHelper.getImage(IImageKeys.CREATE_VOLUME_BIG)); + imageHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + // TODO: Override appropriate method and handle hyperlink event + }); + + imageHyperlink = toolkit.createImageHyperlink(section, SWT.NONE); + imageHyperlink.setText("Add Server(s)"); + imageHyperlink.setImage(guiHelper.getImage(IImageKeys.ADD_SERVER_BIG)); + imageHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + // TODO: Override appropriate method and handle hyperlink event + }); + } + + private void createSections(Composite parent) { + form = guiHelper.setupForm(parent, toolkit, "Cluster Summary"); + + createVolumesSection(); + createServersSection(); + createActionsSection(); + + parent.layout(); // IMP: lays out the form properly + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + if (form != null) { + form.setFocus(); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DetailsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DetailsView.java new file mode 100644 index 00000000..efdb6457 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DetailsView.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.TabItem; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.gui.toolbar.GlusterToolbarManager; +import com.gluster.storage.management.gui.views.details.TabCreatorFactory; +import com.gluster.storage.management.gui.views.details.TabCreatorFactoryImpl; + +/** + * This view is displayed on the right hand side of the platform UI. It updates itself with appropriate tabs + * whenever selection changes on the navigation view (cluster tree) on the left hand side of the UI. + */ +public class DetailsView extends ViewPart implements ISelectionListener { + public static final String ID = DetailsView.class.getName(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private TabFolder tabFolder; + private Entity entity; + private TabCreatorFactory tabCreatorFactory = new TabCreatorFactoryImpl(); + private GlusterToolbarManager toolbarManager; + private IWorkbenchPartSite site; + + public DetailsView() { + super(); + } + + @Override + public void createPartControl(final Composite parent) { + parent.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + + tabFolder = new TabFolder(parent, SWT.TOP); + + // listen to selection event on the navigation tree view + IWorkbenchWindow window = getViewSite().getWorkbenchWindow(); + window.getSelectionService().addSelectionListener(this); + + // Create the toolbar manager + toolbarManager = new GlusterToolbarManager(window); + site = getSite(); + } + + @Override + public void setFocus() { + tabFolder.setFocus(); + } + + private void removeAllTabs() { + for (TabItem item : tabFolder.getItems()) { + item.getControl().dispose(); + item.dispose(); + } + } + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (part instanceof NavigationView && selection instanceof TreeSelection) { + Entity selectedEntity = (Entity) ((TreeSelection) selection).getFirstElement(); + + if (entity == selectedEntity || selectedEntity == null) { + // entity selection has not changed. do nothing. + return; + } + + entity = selectedEntity; + removeAllTabs(); + + // Create tabs for newly selected entity + tabCreatorFactory.getTabCreator(entity).createTabs(entity, tabFolder, toolkit, site); + + // update toolbar buttons visibility based on selected entity + toolbarManager.updateToolbar(entity); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java new file mode 100644 index 00000000..e13912c6 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServerView.java @@ -0,0 +1,90 @@ +/** + * DiscoveredServerView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; + +/** + * @author root + * + */ +public class DiscoveredServerView extends ViewPart { + public static final String ID = DiscoveredServerView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private Server server; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (server == null) { + server = (Server) guiHelper.getSelectedEntity(getSite(), Server.class); + } + createSections(parent); + } + + private void createServerSummarySection() { + Composite section = guiHelper.createSection(form, toolkit, "Summary", null, 2, false); + + toolkit.createLabel(section, "Number of CPUs: ", SWT.NONE); + toolkit.createLabel(section, "" + server.getNumOfCPUs(), SWT.NONE); + + toolkit.createLabel(section, "Total Memory (GB): ", SWT.NONE); + toolkit.createLabel(section, "" + server.getTotalMemory(), SWT.NONE); + + toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + toolkit.createLabel(section, "" + NumberUtil.formatNumber(server.getTotalDiskSpace()), SWT.NONE); + } + + private void createSections(Composite parent) { + String serverName = server.getName(); + form = guiHelper.setupForm(parent, toolkit, "Discovered Server Summary [" + serverName + "]"); + createServerSummarySection(); + + parent.layout(); // IMP: lays out the form properly + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + if (form != null) { + form.setFocus(); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServersView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServersView.java new file mode 100644 index 00000000..69c506f4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DiscoveredServersView.java @@ -0,0 +1,109 @@ +/** + * DiscoveredServersView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.pages.ServersPage; + +/** + * + */ +public class DiscoveredServersView extends ViewPart implements IDoubleClickListener, ISelectionListener { + public static final String ID = DiscoveredServersView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private EntityGroup<Server> servers; + private ServersPage page; + + public DiscoveredServersView() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (servers == null) { + Object selectedObj = guiHelper.getSelectedEntity(getSite(), EntityGroup.class); + if (selectedObj != null && ((EntityGroup) selectedObj).getEntityType() == Server.class) { + servers = (EntityGroup<Server>)selectedObj; + } + } + + page = new ServersPage(parent, getSite(), servers); + page.addDoubleClickListener(this); + getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(NavigationView.ID, this); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + page.setFocus(); + } + + @Override + public void doubleClick(DoubleClickEvent event) { + NavigationView clusterView = (NavigationView) guiHelper.getView(NavigationView.ID); + if (clusterView != null) { + clusterView.selectEntity((Entity) ((StructuredSelection) event.getSelection()).getFirstElement()); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, + * org.eclipse.jface.viewers.ISelection) + */ + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (part instanceof NavigationView && selection instanceof TreeSelection) { + Entity selectedEntity = (Entity) ((TreeSelection) selection).getFirstElement(); + + if (servers == selectedEntity || selectedEntity == null || !(selectedEntity instanceof EntityGroup) + || ((EntityGroup) selectedEntity).getEntityType() != Server.class) { + // entity selection has not changed. do nothing. + return; + } + + servers = (EntityGroup<Server>) selectedEntity; + page.setInput(servers); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java new file mode 100644 index 00000000..260d0d4c --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/DisksView.java @@ -0,0 +1,44 @@ +package com.gluster.storage.management.gui.views; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.DisksPage; + +public class DisksView extends ViewPart { + public static final String ID = DisksView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private EntityGroup<GlusterServer> servers; + private DisksPage page; + + @Override + public void createPartControl(Composite parent) { + if (servers == null) { + servers = (EntityGroup<GlusterServer>)guiHelper.getSelectedEntity(getSite(), EntityGroup.class); + } + + page = new DisksPage(parent, SWT.NONE, getSite(), getAllDisks(servers)); + page.layout(); // IMP: lays out the form properly + } + + private List<Disk> getAllDisks(EntityGroup<GlusterServer> servers) { + List<Disk> disks = new ArrayList<Disk>(); + for(GlusterServer server : (List<GlusterServer>)servers.getEntities()) { + disks.addAll(server.getDisks()); + } + return disks; + } + + @Override + public void setFocus() { + page.setFocus(); + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java new file mode 100644 index 00000000..624d968d --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerDisksView.java @@ -0,0 +1,57 @@ +/** + * GlusterServerDisksView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.ServerDisksPage; + +public class GlusterServerDisksView extends ViewPart { + public static final String ID = GlusterServerDisksView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private GlusterServer server; + private ServerDisksPage page; + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (server == null) { + server = (GlusterServer) guiHelper.getSelectedEntity(getSite(), GlusterServer.class); + } + page = new ServerDisksPage(parent, SWT.NONE, getSite(), server.getDisks()); + + parent.layout(); // IMP: lays out the form properly + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + page.setFocus(); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java new file mode 100644 index 00000000..acc8144d --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerLogsView.java @@ -0,0 +1,59 @@ +/** + * GlusterServerLogsView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.ServerLogsPage; + +public class GlusterServerLogsView extends ViewPart { + public static final String ID = GlusterServerLogsView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private GlusterServer server; + private ServerLogsPage page; + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (server == null) { + server = (GlusterServer) guiHelper.getSelectedEntity(getSite(), GlusterServer.class); + } + + page = new ServerLogsPage(parent, SWT.NONE, server); + + parent.layout(); // IMP: lays out the form properly + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + page.setFocus(); + } +} + diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java new file mode 100644 index 00000000..42a14dd4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServerSummaryView.java @@ -0,0 +1,246 @@ +/** + * GlusterServerSummaryView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.ProgressBar; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.NetworkInterfaceTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.richclientgui.toolbox.gauges.CoolGauge; + +public class GlusterServerSummaryView extends ViewPart { + public static final String ID = GlusterServerSummaryView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private GlusterServer server; + + public enum NETWORK_INTERFACE_TABLE_COLUMN_INDICES { + INTERFACE, IP_ADDRESS, NETMASK, GATEWAY + }; + + private static final String[] NETWORK_INTERFACE_TABLE_COLUMN_NAMES = { "Interface", "IP Address", "Netmask", + "Gateway" }; + + @Override + public void createPartControl(Composite parent) { + if (server == null) { + server = (GlusterServer) guiHelper.getSelectedEntity(getSite(), GlusterServer.class); + } + createSections(parent); + } + + private void createSections(Composite parent) { + String serverName = server.getName(); + form = guiHelper.setupForm(parent, toolkit, "Server Summary [" + serverName + "]"); + createServerSummarySection(server, toolkit, form); + + if (server.getStatus() == SERVER_STATUS.ONLINE) { + Composite section = createNetworkInterfacesSection(server, toolkit, form); + } + + parent.layout(); // IMP: lays out the form properly + } + + private void createServerSummarySection(GlusterServer server, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Summary", null, 2, false); + + // toolkit.createLabel(section, "Preferred Network: ", SWT.NONE); + // toolkit.createLabel(section, server.getPreferredNetworkInterface().getName(), SWT.NONE); + + boolean online = server.getStatus() == SERVER_STATUS.ONLINE; + + if (online) { + toolkit.createLabel(section, "Number of CPUs: ", SWT.NONE); + toolkit.createLabel(section, "" + server.getNumOfCPUs(), SWT.NONE); + + // toolkit.createLabel(section, "CPU Usage (%): ", SWT.NONE); + // toolkit.createLabel(section, online ? "" + server.getCpuUsage() : "NA", SWT.NONE); + + toolkit.createLabel(section, "% CPU Usage (avg): ", SWT.NONE); + CoolGauge gauge = new CoolGauge(section, guiHelper.getImage(IImageKeys.GAUGE_SMALL)); + gauge.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + gauge.setGaugeNeedleColour(Display.getDefault().getSystemColor(SWT.COLOR_RED)); + gauge.setGaugeNeedleWidth(2); + gauge.setGaugeNeedlePivot(new Point(66, 65)); + + gauge.setPoints(getPnts()); + gauge.setLevel(server.getCpuUsage() / 100); + gauge.setToolTipText(server.getCpuUsage() + "%"); + + toolkit.createLabel(section, "Memory Usage: ", SWT.NONE); + ProgressBar memoryUsageBar = new ProgressBar(section, SWT.SMOOTH); + memoryUsageBar.setMinimum(0); + memoryUsageBar.setMaximum((int) Math.round(server.getTotalMemory())); + memoryUsageBar.setSelection((int) Math.round(server.getMemoryInUse())); + memoryUsageBar.setToolTipText("Total: " + server.getTotalMemory() + "GB, In Use: " + + server.getMemoryInUse() + "GB"); + + // toolkit.createLabel(section, "Memory Usage: ", SWT.NONE); + // final CoolProgressBar bar = new CoolProgressBar(section,SWT.HORIZONTAL, + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_LEFT), + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_FILLED), + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_EMPTY), + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_RIGHT)); + // bar.updateProgress(server.getMemoryInUse() / server.getTotalMemory()); + + // toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + // toolkit.createLabel(section, online ? "" + server.getTotalDiskSpace() : "NA", SWT.NONE); + // + // toolkit.createLabel(section, "Disk Space in Use (GB): ", SWT.NONE); + // toolkit.createLabel(section, online ? "" + server.getDiskSpaceInUse() : "NA", SWT.NONE); + + toolkit.createLabel(section, "Disk Usage: ", SWT.NONE); + ProgressBar diskUsageBar = new ProgressBar(section, SWT.SMOOTH); + diskUsageBar.setMinimum(0); + diskUsageBar.setMaximum((int) Math.round(server.getTotalDiskSpace())); + diskUsageBar.setSelection((int) Math.round(server.getDiskSpaceInUse())); + diskUsageBar.setToolTipText("Total: " + NumberUtil.formatNumber(server.getTotalDiskSpace()) + + "GB, In Use: " + NumberUtil.formatNumber(server.getDiskSpaceInUse()) + "GB"); + } + + toolkit.createLabel(section, "Status: ", SWT.NONE); + CLabel lblStatusValue = new CLabel(section, SWT.NONE); + lblStatusValue.setText(server.getStatusStr()); + lblStatusValue.setImage(server.getStatus() == GlusterServer.SERVER_STATUS.ONLINE ? guiHelper + .getImage(IImageKeys.STATUS_ONLINE) : guiHelper.getImage(IImageKeys.STATUS_OFFLINE)); + toolkit.adapt(lblStatusValue, true, true); + } + + private List<Point> getPnts() { + final List<Point> pnts = new ArrayList<Point>(); + pnts.add(new Point(47, 98)); + pnts.add(new Point(34, 84)); + pnts.add(new Point(29, 65)); + pnts.add(new Point(33, 48)); + pnts.add(new Point(48, 33)); + pnts.add(new Point(66, 28)); + pnts.add(new Point(83, 32)); + pnts.add(new Point(98, 47)); + pnts.add(new Point(103, 65)); + pnts.add(new Point(98, 83)); + pnts.add(new Point(84, 98)); + return pnts; + } + + private Composite createNetworkInterfacesSection(GlusterServer server, FormToolkit toolkit, ScrolledForm form) { + final Composite section = guiHelper.createSection(form, toolkit, "Network Interfaces", null, 1, false); + createNetworkInterfacesTableViewer(createTableViewerComposite(section), server); + // Hyperlink changePreferredNetworkLink = toolkit.createHyperlink(section, "Change Preferred Network", + // SWT.NONE); + // changePreferredNetworkLink.addHyperlinkListener(new HyperlinkAdapter() { + // + // @Override + // public void linkActivated(HyperlinkEvent e) { + // new MessageDialog( + // section.getShell(), + // "Gluster Storage Platform", + // guiHelper.getImage(IImageKeys.SERVER), + // "This will show additional controls to help user choose a new network interface. TO BE IMPLEMENTED.", + // MessageDialog.INFORMATION, new String[] { "OK" }, 0).open(); + // } + // }); + return section; + } + + private TableViewer createNetworkInterfacesTableViewer(final Composite parent, GlusterServer server) { + TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new NetworkInterfaceTableLabelProvider()); + tableViewer.setContentProvider(new ArrayContentProvider()); + + setupNetworkInterfaceTable(parent, tableViewer.getTable()); + tableViewer.setInput(server.getNetworkInterfaces().toArray()); + + return tableViewer; + } + + private void setupNetworkInterfaceTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, + NETWORK_INTERFACE_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.INTERFACE, SWT.CENTER, 70); + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.IP_ADDRESS, SWT.CENTER, 100); + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.NETMASK, SWT.CENTER, 70); + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.GATEWAY, SWT.CENTER, 70); + // setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.PREFERRED, SWT.CENTER, 70); + } + + private Composite createTableViewerComposite(Composite parent) { + Composite tableViewerComposite = new Composite(parent, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + tableLayoutData.widthHint = 400; + tableLayoutData.minimumWidth = 400; + // tableLayoutData.grabExcessHorizontalSpace = true; + tableViewerComposite.setLayoutData(tableLayoutData); + return tableViewerComposite; + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES columnIndex, int alignment, + int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } + + @Override + public void setFocus() { + form.setFocus(); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java new file mode 100644 index 00000000..428e55d5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersSummaryView.java @@ -0,0 +1,123 @@ +/** + * GlusterServersSummaryView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.tabcreators.PieChartViewerComposite; + +/** + * + */ +public class GlusterServersSummaryView extends ViewPart { + public static final String ID = GlusterServersSummaryView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private EntityGroup<GlusterServer> servers; + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (servers == null) { + servers = (EntityGroup<GlusterServer>)guiHelper.getSelectedEntity(getSite(), EntityGroup.class); + } + + createSections(parent); + } + + /** + * @param parent + */ + private void createSections(Composite parent) { + form = guiHelper.setupForm(parent, toolkit, "Volumes - Summary"); + + createSummarySection(); + createRunningTasksSection(); + createAlertsSection(); + + + parent.layout(); // IMP: lays out the form properly + } + + private void createSummarySection() { + Composite section = guiHelper.createSection(form, toolkit, "Availability", null, 2, false); + + Double[] values = new Double[] { Double.valueOf(getServerCountByStatus(servers, SERVER_STATUS.ONLINE)), + Double.valueOf(getServerCountByStatus(servers, SERVER_STATUS.OFFLINE)) }; + createStatusChart(section, values); + } + + private int getServerCountByStatus(EntityGroup<GlusterServer> servers, SERVER_STATUS status) { + int count = 0; + for (GlusterServer server : (List<GlusterServer>)servers.getEntities()) { + if (server.getStatus() == status) { + count++; + } + } + return count; + } + + private void createStatusChart(Composite section, Double[] values) { + String[] categories = new String[] { "Online", "Offline" }; + PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, values); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = 250; + data.heightHint = 250; + chartViewerComposite.setLayoutData(data); + } + + + private void createAlertsSection() { + Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 2, false); + + toolkit.createLabel(section, "Any alerts related to servers\nwill be displayed here."); + } + + private void createRunningTasksSection() { + Composite section = guiHelper.createSection(form, toolkit, "Running Tasks", null, 2, false); + + toolkit.createLabel(section, "List of running tasks related to\nservers will be displayed here."); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + form.setFocus(); + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java new file mode 100644 index 00000000..06b1e282 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterServersView.java @@ -0,0 +1,77 @@ +/** + * GlusterServersView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.GlusterServersPage; + +/** + * @author root + * + */ +public class GlusterServersView extends ViewPart implements IDoubleClickListener { + public static final String ID = GlusterServersView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private EntityGroup<GlusterServer> servers; + private GlusterServersPage page; + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (servers == null) { + servers = (EntityGroup<GlusterServer>)guiHelper.getSelectedEntity(getSite(), EntityGroup.class); + } + + page = new GlusterServersPage(parent, SWT.NONE, servers); + page.addDoubleClickListener(this); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + page.setFocus(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.viewers.IDoubleClickListener#doubleClick(org.eclipse.jface.viewers.DoubleClickEvent) + */ + @Override + public void doubleClick(DoubleClickEvent event) { + NavigationView clusterView = (NavigationView) guiHelper.getView(NavigationView.ID); + if (clusterView != null) { + clusterView.selectEntity((Entity) ((StructuredSelection) event.getSelection()).getFirstElement()); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java new file mode 100644 index 00000000..2b2645fc --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/GlusterViewsManager.java @@ -0,0 +1,130 @@ +/** + * GlusterViewsManager.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; + +import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Volume; + +/** + * @see ViewsManager + */ +public class GlusterViewsManager implements ViewsManager { + private IWorkbenchPage page; + + public GlusterViewsManager(IWorkbenchPage page) { + this.page = page; + } + + /* (non-Javadoc) + * @see com.gluster.storage.management.gui.views.ViewsManager#updateViews(com.gluster.storage.management.core.model.Entity) + */ + @Override + public void updateViews(Entity entity) { + closeAllViews(); + + + try { + if (entity instanceof EntityGroup) { + showViewsForEntityGroup((EntityGroup)entity); + } else if (entity.getClass() == Server.class) { + showViewsForDiscoveredServer((Server)entity); + } else if (entity.getClass() == GlusterServer.class) { + showViewsForGlusterServer((GlusterServer)entity); + } else if (entity instanceof Volume) { + showViewsForVolume((Volume)entity); + } else if (entity instanceof Cluster) { + showViewsForCluster((Cluster)entity); + } + } catch (PartInitException e) { + e.printStackTrace(); + } + } + + /** + * + */ + private void closeAllViews() { + IViewReference[] viewReferences = page.getViewReferences(); + for (final IViewReference viewReference : viewReferences) { + if (!viewReference.getId().equals(NavigationView.ID)) { + page.hideView(viewReference); + } + } + } + + private void showViewsForCluster(Cluster cluster) throws PartInitException { + page.showView(ClusterSummaryView.ID); + } + + private void showViewsForVolume(Volume volume) throws PartInitException { + page.showView(VolumeSummaryView.ID); + page.showView(VolumeDisksView.ID, null, IWorkbenchPage.VIEW_CREATE); + page.showView(VolumeOptionsView.ID, null, IWorkbenchPage.VIEW_CREATE); + page.showView(VolumeLogsView.ID, null, IWorkbenchPage.VIEW_CREATE); + } + + private void showViewsForGlusterServer(GlusterServer server) throws PartInitException { + page.showView(GlusterServerSummaryView.ID); + if (server.getStatus() == GlusterServer.SERVER_STATUS.ONLINE) { + page.showView(GlusterServerDisksView.ID, null, IWorkbenchPage.VIEW_CREATE); + page.showView(GlusterServerLogsView.ID, null, IWorkbenchPage.VIEW_CREATE); + } + } + + private void showViewsForDiscoveredServer(Server server) throws PartInitException { + page.showView(DiscoveredServerView.ID); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void showViewsForEntityGroup(EntityGroup entityGroup) throws PartInitException { + Class entityType = entityGroup.getEntityType(); + if (entityType == Server.class) { + showViewForServers(entityGroup); + } else if (entityType == Volume.class) { + showViewsForVolumes(entityGroup); + } else if (entityType == GlusterServer.class) { + showViewsForGlusterServers(entityGroup); + } + } + + private void showViewsForGlusterServers(EntityGroup<GlusterServer> server) throws PartInitException { + page.showView(GlusterServersSummaryView.ID); + page.showView(GlusterServersView.ID, null, IWorkbenchPage.VIEW_CREATE); + page.showView(DisksView.ID, null, IWorkbenchPage.VIEW_CREATE); + } + + private void showViewsForVolumes(EntityGroup<Volume> volumes) throws PartInitException { + page.showView(VolumesSummaryView.ID); + page.showView(VolumesView.ID, null, IWorkbenchPage.VIEW_CREATE); + } + + private void showViewForServers(EntityGroup<Server> servers) throws PartInitException { + page.showView(DiscoveredServersView.ID); + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java new file mode 100644 index 00000000..4de5b61a --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/NavigationView.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.core.runtime.Platform; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.model.BaseWorkbenchContentProvider; +import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.DefaultClusterListener; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.Event; +import com.gluster.storage.management.core.model.GlusterDataModel; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.toolbar.GlusterToolbarManager; +import com.gluster.storage.management.gui.views.navigator.ClusterAdapterFactory; + +public class NavigationView extends ViewPart implements ISelectionListener { + public static final String ID = NavigationView.class.getName(); + private GlusterDataModel model; + private TreeViewer treeViewer; + private IAdapterFactory adapterFactory = new ClusterAdapterFactory(); + private GlusterToolbarManager toolbarManager; + private Entity entity; + private GlusterViewsManager viewsManager; + + @Override + public void createPartControl(Composite parent) { + createNavigationTree(parent); + + // Create the views and toolbar managers + toolbarManager = new GlusterToolbarManager(getSite().getWorkbenchWindow()); + viewsManager = new GlusterViewsManager(getSite().getPage()); + + // listen to selection events to update views/toolbar accordingly + getSite().getPage().addSelectionListener(this); + } + + private void createNavigationTree(Composite parent) { + model = GlusterDataModelManager.getInstance().getModel(); + + Platform.getAdapterManager().registerAdapters(adapterFactory, Entity.class); + treeViewer = new TreeViewer(parent, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL); + treeViewer.setLabelProvider(WorkbenchLabelProvider.getDecoratingWorkbenchLabelProvider()); + treeViewer.setContentProvider(new BaseWorkbenchContentProvider()); + treeViewer.setInput(model); + treeViewer.expandAll(); + // select the first element by default + treeViewer.setSelection(new StructuredSelection(model.getChildren().get(0))); + + setupContextMenu(); + + // register as selection provider so that other views can listen to any selection events on the tree + getSite().setSelectionProvider(treeViewer); + + // Refresh the navigation tree whenever there is a change to the data model + GlusterDataModelManager.getInstance().addClusterListener(new DefaultClusterListener() { + public void clusterChanged() { + treeViewer.refresh(); + } + + @Override + public void volumeChanged(Volume volume, Event event) { + super.volumeChanged(volume, event); + selectEntity(volume); // this makes sure that the toolbar buttons get updated accoring to new status + } + + @Override + public void volumeCreated(Volume volume) { + super.volumeCreated(volume); + selectEntity(volume); + } + }); + } + + private void setupContextMenu() { + MenuManager menuManager = new MenuManager("&Gluster", "gluster.context.menu"); + Menu contextMenu = menuManager.createContextMenu(treeViewer.getControl()); + treeViewer.getTree().setMenu(contextMenu); + getSite().registerContextMenu(menuManager, treeViewer); + } + + public void selectEntity(Entity entity) { + treeViewer.setSelection(new StructuredSelection(entity)); + treeViewer.reveal(entity); + setFocus(); // this ensures that the "selection changed" event gets fired + } + + @Override + public void setFocus() { + treeViewer.getControl().setFocus(); + } + + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (part instanceof NavigationView && selection instanceof TreeSelection) { + Entity selectedEntity = (Entity) ((TreeSelection) selection).getFirstElement(); + + if (selectedEntity != null && selectedEntity != entity) { + entity = selectedEntity; + + // update views and toolbar buttons visibility based on selected entity + viewsManager.updateViews(entity); + toolbarManager.updateToolbar(entity); + + // Opening of other views may cause navigation tree to lose focus; get it back. + setFocus(); + } + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ViewsManager.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ViewsManager.java new file mode 100644 index 00000000..2b33308e --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/ViewsManager.java @@ -0,0 +1,38 @@ +/** + * ViewsManager.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import com.gluster.storage.management.core.model.Entity; + +/** + * Whenever the current selection/action demands opening different set of views, the views manager is used to open + * appropriate views. + */ +public interface ViewsManager { + /** + * Updates the views for given entity. This typically means that user is working with the given entity, and hence + * the views related to that entity should be made visible, and other un-related views should be hidden. + * + * @param entity + * The entity for which views are to be updated + */ + public void updateViews(Entity entity); +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeDisksView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeDisksView.java new file mode 100644 index 00000000..cbf6736b --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeDisksView.java @@ -0,0 +1,39 @@ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.DisksPage; + +public class VolumeDisksView extends ViewPart { + public static final String ID = VolumeDisksView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private DisksPage page; + private Volume volume; + + @Override + public void createPartControl(Composite parent) { + if (volume == null) { + volume = (Volume) guiHelper.getSelectedEntity(getSite(), Volume.class); + } + + createPage(parent); + } + + /** + * @param parent + */ + private void createPage(Composite parent) { + page = new DisksPage(parent, SWT.NONE, getSite(), volume.getDisks()); + parent.layout(); // IMP: lays out the form properly + } + + @Override + public void setFocus() { + page.setFocus(); + } +} + diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java new file mode 100644 index 00000000..b6c98ad3 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeLogsView.java @@ -0,0 +1,35 @@ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.VolumeLogsPage; + +public class VolumeLogsView extends ViewPart { + VolumeLogsPage logsPage; + public static final String ID = VolumeLogsView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private Volume volume; + + @Override + public void createPartControl(Composite parent) { + if (volume == null) { + volume = (Volume) guiHelper.getSelectedEntity(getSite(), Volume.class); + } + + createPage(parent); + } + + private void createPage(Composite parent) { + logsPage = new VolumeLogsPage(parent, SWT.NONE, volume); + parent.layout(); // IMP: lays out the form properly + } + + @Override + public void setFocus() { + logsPage.setFocus(); + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java new file mode 100644 index 00000000..e8695737 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeOptionsView.java @@ -0,0 +1,36 @@ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.VolumeOptionsPage; + +public class VolumeOptionsView extends ViewPart { + public static final String ID = VolumeOptionsView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private VolumeOptionsPage page; + private Volume volume; + + @Override + public void createPartControl(Composite parent) { + if (volume == null) { + volume = (Volume) guiHelper.getSelectedEntity(getSite(), Volume.class); + } + + createPage(parent); + } + + private void createPage(Composite parent) { + page = new VolumeOptionsPage(parent, SWT.NONE, volume); + parent.layout(); // IMP: lays out the form properly + } + + @Override + public void setFocus() { + page.setFocus(); + } +} + diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java new file mode 100644 index 00000000..798c2a40 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeSummaryView.java @@ -0,0 +1,270 @@ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.DefaultClusterListener; +import com.gluster.storage.management.core.model.Event; +import com.gluster.storage.management.core.model.Event.EVENT_TYPE; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.NAS_PROTOCOL; +import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.toolbar.GlusterToolbarManager; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class VolumeSummaryView extends ViewPart { + public static final String ID = VolumeSummaryView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private Volume volume; + private CLabel lblStatusValue; + private DefaultClusterListener volumeChangedListener; + + @Override + public void createPartControl(Composite parent) { + if (volume == null) { + volume = (Volume) guiHelper.getSelectedEntity(getSite(), Volume.class); + } + + createSections(parent); + + // Refresh the navigation tree whenever there is a change to the data model + volumeChangedListener = new DefaultClusterListener() { + @Override + public void volumeChanged(Volume volume, Event event) { + if(event.getEventType() == EVENT_TYPE.VOLUME_STATUS_CHANGED) { + updateVolumeStatusLabel(); + new GlusterToolbarManager(getSite().getWorkbenchWindow()).updateToolbar(volume); + } + } + }; + GlusterDataModelManager.getInstance().addClusterListener(volumeChangedListener); + } + + /* (non-Javadoc) + * @see org.eclipse.ui.part.WorkbenchPart#dispose() + */ + @Override + public void dispose() { + super.dispose(); + GlusterDataModelManager.getInstance().removeClusterListener(volumeChangedListener); + } + + private void createSections(Composite parent) { + form = guiHelper.setupForm(parent, toolkit, "Volume Properties [" + volume.getName() + "]"); + + createVolumePropertiesSection(); + createVolumeMountingInfoSection(); + createVolumeAlertsSection(); + + parent.layout(); // IMP: lays out the form properly + } + + private void createVolumeAlertsSection() { + Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 3, false); + toolkit.createLabel(section, "Volume related alerts will be displayed here"); + } + + private void createVolumeMountingInfoSection() { + Composite section = guiHelper.createSection(form, toolkit, "Mounting Information", null, 3, false); + toolkit.createLabel(section, "Information about mounting the\nvolume will be printed here"); + } + + /** + * + */ + private void createVolumePropertiesSection() { + Composite section = guiHelper.createSection(form, toolkit, "Properties", null, 3, false); + + createVolumeTypeField(section); + + VOLUME_TYPE volumeType = volume.getVolumeType(); + if (volumeType == VOLUME_TYPE.DISTRIBUTED_MIRROR) { + createReplicaCountField(section); + } + + if (volumeType == VOLUME_TYPE.DISTRIBUTED_STRIPE) { + createStripeCountField(section); + } + + createNumOfDisksField(section); + createDiskSpaceField(section); + createTransportTypeField(section); + createNASProtocolField(section); + createAccessControlField(section); + createStatusField(section); + } + + private GridData createDefaultLayoutData() { + GridData layoutData = new GridData(); + layoutData.minimumWidth = 150; + layoutData.widthHint = 150; + return layoutData; + } + + private void createAccessControlField(Composite section) { + toolkit.createLabel(section, "Access Control: ", SWT.NONE); + Text accessControlText = toolkit.createText(section, volume.getAccessControlList()); + accessControlText.setLayoutData(createDefaultLayoutData()); + accessControlText.setEnabled(false); + createChangeLinkForAccessControl(section, accessControlText); + } + + private void createChangeLinkForAccessControl(Composite section, final Text accessControlText) { + final Hyperlink changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); + changeLink.addHyperlinkListener(new HyperlinkAdapter() { + + private void finishEdit() { + // TODO: Update value to back-end + // TODO: Validation of entered text + volume.setAccessControlList(accessControlText.getText()); + accessControlText.setEnabled(false); + changeLink.setText("change"); + } + + private void startEdit() { + accessControlText.setEnabled(true); + changeLink.setText("update"); + } + + @Override + public void linkActivated(HyperlinkEvent e) { + if (accessControlText.isEnabled()) { + // we were already in edit mode. + finishEdit(); + } else { + // Get in to edit mode + startEdit(); + } + } + }); + } + + private void createNASProtocolField(Composite section) { + toolkit.createLabel(section, "NAS Protocols: ", SWT.NONE); + + Composite nasProtocolsComposite = toolkit.createComposite(section); + nasProtocolsComposite.setLayout(new FillLayout()); + + createCheckbox(nasProtocolsComposite, "Gluster", true); + final Button nfsCheckBox = createCheckbox(nasProtocolsComposite, "NFS", + volume.getNASProtocols().contains(NAS_PROTOCOL.NFS)); + + createChangeLinkForNASProtocol(section, nfsCheckBox); + } + + private Button createCheckbox(Composite parent, String label, boolean selected) { + final Button checkBox = toolkit.createButton(parent, label, SWT.CHECK); + checkBox.setEnabled(false); + checkBox.setSelection(selected); + return checkBox; + } + + private void createChangeLinkForNASProtocol(Composite section, final Button nfsCheckBox) { + final Hyperlink changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); + changeLink.addHyperlinkListener(new HyperlinkAdapter() { + + private void finishEdit() { + // TODO: Update value to back-end + if (nfsCheckBox.getSelection()) { + volume.enableNFS(); + } else { + volume.disableNFS(); + } + nfsCheckBox.setEnabled(false); + changeLink.setText("change"); + } + + private void startEdit() { + nfsCheckBox.setEnabled(true); + changeLink.setText("update"); + } + + @Override + public void linkActivated(HyperlinkEvent e) { + if (nfsCheckBox.isEnabled()) { + // we were already in edit mode. + finishEdit(); + } else { + // Get in to edit mode + startEdit(); + } + } + }); + } + + private void createDiskSpaceField(Composite section) { + Label diskSpaceLabel = toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + diskSpaceLabel.setToolTipText("<b>bold</b>normal"); + toolkit.createLabel(section, "" + NumberUtil.formatNumber(volume.getTotalDiskSpace()), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createStatusField(Composite section) { + toolkit.createLabel(section, "Status: ", SWT.NONE); + + lblStatusValue = new CLabel(section, SWT.NONE); + updateVolumeStatusLabel(); + + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void updateVolumeStatusLabel() { + lblStatusValue.setText(volume.getStatusStr()); + lblStatusValue.setImage(volume.getStatus() == Volume.VOLUME_STATUS.ONLINE ? guiHelper + .getImage(IImageKeys.STATUS_ONLINE) : guiHelper.getImage(IImageKeys.STATUS_OFFLINE)); + lblStatusValue.redraw(); + } + + private void createTransportTypeField(Composite section) { + toolkit.createLabel(section, "Transport Type: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getTransportTypeStr(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createNumOfDisksField(Composite section) { + toolkit.createLabel(section, "Number of Disks: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getNumOfDisks(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createStripeCountField(Composite section) { + toolkit.createLabel(section, "Stripe Count: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getStripeCount(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createReplicaCountField(Composite section) { + toolkit.createLabel(section, "Replica Count: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getReplicaCount(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createVolumeTypeField(Composite section) { + toolkit.createLabel(section, "Volume Type: ", SWT.NONE); + toolkit.createLabel(section, volume.getVolumeTypeStr(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); + } + + @Override + public void setFocus() { + form.setFocus(); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeView.java new file mode 100644 index 00000000..1983f6e4 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumeView.java @@ -0,0 +1,90 @@ +/** + * DiscoveredServerView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.utils.GUIHelper; + +/** + * @author root + * + */ +public class VolumeView extends ViewPart { + public static final String ID = VolumeView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private Server server; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (server == null) { + server = (Server) guiHelper.getSelectedEntity(getSite(), Server.class); + } + createSections(parent, server, toolkit); + } + + private void createServerSummarySection(Server server, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Summary", null, 2, false); + + toolkit.createLabel(section, "Number of CPUs: ", SWT.NONE); + toolkit.createLabel(section, "" + server.getNumOfCPUs(), SWT.NONE); + + toolkit.createLabel(section, "Total Memory (GB): ", SWT.NONE); + toolkit.createLabel(section, "" + server.getTotalMemory(), SWT.NONE); + + toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + toolkit.createLabel(section, "" + NumberUtil.formatNumber(server.getTotalDiskSpace()), SWT.NONE); + } + + private void createSections(Composite parent, Server server, FormToolkit toolkit) { + String serverName = server.getName(); + form = guiHelper.setupForm(parent, toolkit, "Discovered Server Summary [" + serverName + "]"); + createServerSummarySection(server, toolkit, form); + + parent.layout(); // IMP: lays out the form properly + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + if (form != null) { + form.setFocus(); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java new file mode 100644 index 00000000..9477e170 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesSummaryView.java @@ -0,0 +1,145 @@ +/** + * DiscoveredServerView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.constants.CoreConstants; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.GlusterDataModel; +import com.gluster.storage.management.client.GlusterDataModelManager; +import com.gluster.storage.management.core.model.RunningTask; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.tabcreators.PieChartViewerComposite; + +/** + * + */ +public class VolumesSummaryView extends ViewPart { + public static final String ID = VolumesSummaryView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private ScrolledForm form; + private EntityGroup<Volume> volumes; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (volumes == null) { + Object selectedObj = guiHelper.getSelectedEntity(getSite(), EntityGroup.class); + if (selectedObj != null && ((EntityGroup) selectedObj).getEntityType() == Volume.class) { + volumes = (EntityGroup<Volume>)selectedObj; + } + } + + createSections(parent); + } + + private void createSections(Composite parent) { + form = guiHelper.setupForm(parent, toolkit, "Volumes - Summary"); + createSummarySection(); + createRunningTasksSection(); + createAlertsSection(); + + parent.layout(); // IMP: lays out the form properly + } + + private void createAlertsSection() { + Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 2, false); + + toolkit.createLabel(section, "Any alerts related to volumes\nwill be displayed here."); + } + + private void createRunningTasksSection() { + Composite section = guiHelper.createSection(form, toolkit, "Running Tasks", null, 2, false); + + GlusterDataModelManager modelManager = GlusterDataModelManager.getInstance(); + GlusterDataModel model = modelManager.getModel(); + Cluster cluster = (Cluster) model.getChildren().get(0); // Assume the first/root node of the model is cluster (invisible) + + List<RunningTask> runningTasks = cluster.getRunningTasks(); + String taskMessage = ""; + for(RunningTask task : runningTasks) { + if (task.getStatus().isPercentageSupported()) { + //TODO Progress bar + } + //TODO show different labels for each task + taskMessage = taskMessage + CoreConstants.NEWLINE + task.getDescription(); + } + toolkit.createLabel(section, taskMessage); + } + + private void createSummarySection() { + Composite section = guiHelper.createSection(form, toolkit, "Availability", null, 2, false); + + Double[] values = new Double[] { Double.valueOf(getVolumeCountByStatus(volumes, VOLUME_STATUS.ONLINE)), + Double.valueOf(getVolumeCountByStatus(volumes, VOLUME_STATUS.OFFLINE)) }; + createStatusChart(toolkit, section, values); + } + + private int getVolumeCountByStatus(EntityGroup<Volume> volumes, VOLUME_STATUS status) { + int count = 0; + for (Volume volume : (List<Volume>) volumes.getEntities()) { + if (volume.getStatus() == status) { + count++; + } + } + return count; + } + + private void createStatusChart(FormToolkit toolkit, Composite section, Double[] values) { + String[] categories = new String[] { "Online", "Offline" }; + PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, + values); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = 250; + data.heightHint = 250; + chartViewerComposite.setLayoutData(data); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + if (form != null) { + form.setFocus(); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesView.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesView.java new file mode 100644 index 00000000..4ccf5325 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/VolumesView.java @@ -0,0 +1,108 @@ +/** + * DiscoveredServersView.java + * + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + */ +package com.gluster.storage.management.gui.views; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.ISelectionListener; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.part.ViewPart; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.pages.ServersPage; +import com.gluster.storage.management.gui.views.pages.VolumesPage; + +/** + * + */ +public class VolumesView extends ViewPart implements IDoubleClickListener, ISelectionListener { + public static final String ID = VolumesView.class.getName(); + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + private EntityGroup<Volume> volumes; + private VolumesPage page; + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite) + */ + @Override + public void createPartControl(Composite parent) { + if (volumes == null) { + Object selectedObj = guiHelper.getSelectedEntity(getSite(), EntityGroup.class); + if (selectedObj != null && ((EntityGroup) selectedObj).getEntityType() == Volume.class) { + volumes = (EntityGroup<Volume>)selectedObj; + } + } + + page = new VolumesPage(parent, getSite(), volumes); + page.addDoubleClickListener(this); + getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(NavigationView.ID, this); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + page.setFocus(); + } + + @Override + public void doubleClick(DoubleClickEvent event) { + NavigationView clusterView = (NavigationView) guiHelper.getView(NavigationView.ID); + if (clusterView != null) { + clusterView.selectEntity((Entity) ((StructuredSelection) event.getSelection()).getFirstElement()); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, + * org.eclipse.jface.viewers.ISelection) + */ + @Override + public void selectionChanged(IWorkbenchPart part, ISelection selection) { + if (part instanceof NavigationView && selection instanceof TreeSelection) { + Entity selectedEntity = (Entity) ((TreeSelection) selection).getFirstElement(); + + if (volumes == selectedEntity || selectedEntity == null || !(selectedEntity instanceof EntityGroup) + || ((EntityGroup) selectedEntity).getEntityType() != Volume.class) { + // entity selection has not changed. do nothing. + return; + } + + volumes = (EntityGroup<Volume>) selectedEntity; + page.setInput(volumes); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractDisksPage.java new file mode 100644 index 00000000..e00fe3f8 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/AbstractDisksPage.java @@ -0,0 +1,315 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import java.util.List; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TableEditor; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ImageHyperlink; +import org.eclipse.ui.progress.IProgressConstants; + +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.Disk.DISK_STATUS; +import com.gluster.storage.management.gui.Application; +import com.gluster.storage.management.gui.IEntityListener; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.jobs.InitializeDiskJob; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public abstract class AbstractDisksPage extends Composite implements IEntityListener { + protected final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + protected TableViewer tableViewer; + private IWorkbenchSite site; + protected static final GUIHelper guiHelper = GUIHelper.getInstance(); + + /** + * Setup properties of the table e.g. column headers, widths, etc. + * + * @param parent + * The parent composite. (TableColumnLayout has to be set on this) + * @param table + * The table to be set up + */ + protected abstract void setupDiskTable(Composite parent, Table table); + + /** + * @return The label provider to be used with the disk table viewer + */ + protected abstract ITableLabelProvider getTableLabelProvider(); + + /** + * @return Index of the "status" column in the table. Return -1 if status column is not displayed + */ + protected abstract int getStatusColumnIndex(); + + private void init(final Composite parent, IWorkbenchSite site, List<Disk> disks) { + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + + this.site = site; + + setupPageLayout(); + Text filterText = guiHelper.createFilterText(toolkit, this); + setupDiskTableViewer(createTableViewerComposite(), filterText); + + tableViewer.setInput(disks); + setupStatusCellEditor(); // creates hyperlinks for "unitialized" disks + + site.setSelectionProvider(tableViewer); + Application.getApplication().addEntityListener(this); + + parent.layout(); // Important - this actually paints the table + + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + /** + * Ideally not required. However the table viewer is not getting laid out properly on performing + * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window + */ + addPaintListener(new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + parent.layout(); + } + }); + } + + public AbstractDisksPage(final Composite parent, int style, IWorkbenchSite site, List<Disk> disks) { + super(parent, style); + init(parent, site, disks); + } + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(1, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + } + + private void createInitializeLink(final TableItem item, final int rowNum, final Disk disk) { + final Table table = tableViewer.getTable(); + final TableEditor editor = new TableEditor(table); + editor.grabHorizontal = true; + editor.horizontalAlignment = SWT.RIGHT; + + table.addPaintListener(new PaintListener() { + private TableItem myItem = item; + private int myRowNum = rowNum; + private ImageHyperlink myLink = null; + private TableEditor myEditor = null; + + private void createLinkFor(Disk disk1, TableItem item1, int rowNum1) { + myItem = item1; + myRowNum = rowNum1; + + myEditor = new TableEditor(table); + myEditor.grabHorizontal = true; + myEditor.horizontalAlignment = SWT.RIGHT; + + myLink = toolkit.createImageHyperlink(table, SWT.NONE); + // link.setImage(guiHelper.getImage(IImageKeys.DISK_UNINITIALIZED)); + myLink.setText("Initialize"); + myLink.addHyperlinkListener(new StatusLinkListener(myLink, myEditor, myItem, tableViewer, disk1, site)); + + myEditor.setEditor(myLink, item1, getStatusColumnIndex()); + + myItem.addDisposeListener(new DisposeListener() { + @Override + public void widgetDisposed(DisposeEvent e) { + myLink.dispose(); + myEditor.dispose(); + } + }); + } + + @Override + public void paintControl(PaintEvent e) { + int itemCount = table.getItemCount(); + + // Find the table item corresponding to our disk + Disk disk1 = null; + int rowNum1 = -1; + TableItem item1 = null; + for (int i = 0; i < itemCount; i++) { + item1 = table.getItem(i); + disk1 = (Disk) item1.getData(); + if (disk1 != null && disk1 == disk) { + rowNum1 = i; + break; + } + } + + if (rowNum1 == -1) { + // item disposed and disk not visible. nothing to do. + return; + } + + if (myEditor == null || myItem.isDisposed()) { + // item visible, and + // either editor never created, OR + // old item disposed. create the link for it + createLinkFor(disk1, item1, rowNum1); + } + + if (rowNum1 != myRowNum) { + // disk visible, but at a different row num. re-create the link + myLink.dispose(); + myEditor.dispose(); + createLinkFor(disk1, item1, rowNum1); + } + + myEditor.layout(); // IMPORTANT. Without this, the link location goes for a toss on maximize + restore + } + }); + } + + private void setupStatusCellEditor() { + final TableViewer viewer = tableViewer; + final Table table = viewer.getTable(); + for (int i = 0; i < table.getItemCount(); i++) { + final TableItem item = table.getItem(i); + if (item.isDisposed() || item.getData() == null) { + continue; + } + final Disk disk = (Disk) item.getData(); + if (disk.isUninitialized()) { + createInitializeLink(item, i, disk); + } + } + } + + private Composite createTableViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return tableViewerComposite; + } + + private TableViewer createDiskTableViewer(Composite parent) { + tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + + tableViewer.setLabelProvider(getTableLabelProvider()); + tableViewer.setContentProvider(new ArrayContentProvider()); + + setupDiskTable(parent, tableViewer.getTable()); + + return tableViewer; + } + + private void setupDiskTableViewer(Composite parent, final Text filterText) { + tableViewer = createDiskTableViewer(parent); + // Create a case insensitive filter for the table viewer using the filter text field + guiHelper.createFilter(tableViewer, filterText, false); + } + + private final class StatusLinkListener extends HyperlinkAdapter { + private final Disk disk; + private final TableEditor myEditor; + private final ImageHyperlink myLink; + private final TableViewer viewer; + private final IWorkbenchSite site; + + private StatusLinkListener(ImageHyperlink link, TableEditor editor, TableItem item, TableViewer viewer, + Disk disk, IWorkbenchSite site) { + this.disk = disk; + this.viewer = viewer; + this.myEditor = editor; + this.myLink = link; + this.site = site; + } + + private void updateStatus(final DISK_STATUS status, final boolean disposeEditor) { + if (disposeEditor) { + myLink.dispose(); + myEditor.dispose(); + } + disk.setStatus(status); + viewer.update(disk, new String[] { "status" }); + Application.getApplication().entityChanged(disk, new String[] { "status" }); + } + + @Override + public void linkActivated(HyperlinkEvent e) { + updateStatus(DISK_STATUS.INITIALIZING, true); + + try { + site.getWorkbenchWindow().getActivePage().showView(IProgressConstants.PROGRESS_VIEW_ID); + } catch (PartInitException e1) { + e1.printStackTrace(); + throw new GlusterRuntimeException("Could not open the progress view!", e1); + } + + new InitializeDiskJob(disk).schedule(); + } + } + + @Override + public void entityChanged(final Entity entity, final String[] paremeters) { + if (!(entity instanceof Disk)) { + return; + } + final Disk disk = (Disk) entity; + + Display.getDefault().syncExec(new Runnable() { + public void run() { + tableViewer.update(disk, paremeters); + + if (disk.isUninitialized()) { + Table table = tableViewer.getTable(); + + for (int rowNum = 0; rowNum < table.getItemCount(); rowNum++) { + TableItem item = table.getItem(rowNum); + if (item.getData() == disk) { + createInitializeLink(item, rowNum, disk); + } + } + } + } + }); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/DisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/DisksPage.java new file mode 100644 index 00000000..9ea962de --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/DisksPage.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import java.util.List; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.IWorkbenchSite; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.gui.DiskTableLabelProvider; + +public class DisksPage extends AbstractDisksPage { + + public enum DISK_TABLE_COLUMN_INDICES { + SERVER, DISK, SPACE, SPACE_IN_USE, STATUS + }; + + private static final String[] DISK_TABLE_COLUMN_NAMES = new String[] { "Server", "Disk", "Space (GB)", + "Space in Use (GB)", "Status" }; + + public DisksPage(final Composite parent, int style, IWorkbenchSite site, List<Disk> disks) { + super(parent, style, site, disks); + } + + @Override + protected void setupDiskTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, DISK_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SERVER.ordinal(), SWT.CENTER, 100); + guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.DISK.ordinal(), SWT.CENTER, 100); + guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SPACE.ordinal(), SWT.CENTER, 90); + guiHelper.setColumnProperties(table, DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE.ordinal(), SWT.CENTER, 90); + } + + @Override + protected ITableLabelProvider getTableLabelProvider() { + return new DiskTableLabelProvider(); + } + + @Override + protected int getStatusColumnIndex() { + return DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(); + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java new file mode 100644 index 00000000..01766115 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/GlusterServersPage.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.gui.EntityGroupContentProvider; +import com.gluster.storage.management.gui.GlusterServerTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class GlusterServersPage extends Composite { + + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private TableViewer tableViewer; + private GUIHelper guiHelper = GUIHelper.getInstance(); + + public enum GLUSTER_SERVER_TABLE_COLUMN_INDICES { + NAME, IP_ADDRESSES, NUM_OF_CPUS, TOTAL_MEMORY, TOTAL_DISK_SPACE, STATUS // Removed PREFERRED_NETWORK + }; + + private static final String[] GLUSTER_SERVER_TABLE_COLUMN_NAMES = new String[] { "Name", + "IP Address(es)", "Number\nof CPUs", "Total\nMemory (GB)", "Total Disk\n Space (GB)", "Status" }; // Removed "Preferred\nNetwork", + + public GlusterServersPage(Composite parent, int style) { + super(parent, style); + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + setupPageLayout(); + Text filterText = guiHelper.createFilterText(toolkit, this); + setupServerTableViewer(filterText); + } + + public GlusterServersPage(final Composite parent, int style, EntityGroup<GlusterServer> servers) { + this(parent, style); + + tableViewer.setInput(servers); + parent.layout(); // Important - this actually paints the table + + /** + * Ideally not required. However the table viewer is not getting laid out properly on performing + * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window + */ + addPaintListener(new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + parent.layout(); + } + }); + } + + public void addDoubleClickListener(IDoubleClickListener listener) { + tableViewer.addDoubleClickListener(listener); + } + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(1, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + } + + private void setupServerTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, GLUSTER_SERVER_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.NAME, SWT.CENTER, 100); + setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.STATUS, SWT.CENTER, 70); + // setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.PREFERRED_NETWORK, SWT.CENTER, 90); + setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.NUM_OF_CPUS, SWT.CENTER, 90); + //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.CPU_USAGE, SWT.CENTER, 90); + setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_MEMORY, SWT.CENTER, 90); + //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.MEMORY_IN_USE, SWT.CENTER, 90); + setColumnProperties(table, GLUSTER_SERVER_TABLE_COLUMN_INDICES.TOTAL_DISK_SPACE, SWT.CENTER, 90); + //setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90); + } + + private TableViewer createServerTableViewer(Composite parent) { + TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + //TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new GlusterServerTableLabelProvider()); + tableViewer.setContentProvider(new EntityGroupContentProvider<GlusterServer>()); + + setupServerTable(parent, tableViewer.getTable()); + + return tableViewer; + } + + private Composite createTableViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return tableViewerComposite; + } + + private void setupServerTableViewer(final Text filterText) { + Composite tableViewerComposite = createTableViewerComposite(); + tableViewer = createServerTableViewer(tableViewerComposite); + // Create a case insensitive filter for the table viewer using the filter text field + guiHelper.createFilter(tableViewer, filterText, false); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, GLUSTER_SERVER_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerDisksPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerDisksPage.java new file mode 100644 index 00000000..bace2af9 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerDisksPage.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import java.util.List; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.ui.IWorkbenchSite; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.gui.ServerDiskTableLabelProvider; +import com.gluster.storage.management.gui.TableLabelProviderAdapter; + +public class ServerDisksPage extends AbstractDisksPage { + public ServerDisksPage(Composite parent, int style, IWorkbenchSite site, List<Disk> disks) { + super(parent, style, site, disks); + } + + public enum SERVER_DISK_TABLE_COLUMN_INDICES { + DISK, SPACE, SPACE_IN_USE, STATUS + }; + + private static final String[] SERVER_DISK_TABLE_COLUMN_NAMES = new String[] { "Disk", "Space (GB)", + "Space in Use (GB)", "Status" }; + + @Override + protected void setupDiskTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, SERVER_DISK_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK.ordinal(), SWT.CENTER, 100); + guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.SPACE.ordinal(), SWT.CENTER, 90); + guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.SPACE_IN_USE.ordinal(), SWT.CENTER, 90); + guiHelper.setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(), SWT.LEFT, 90); + } + + @Override + protected int getStatusColumnIndex() { + return SERVER_DISK_TABLE_COLUMN_INDICES.STATUS.ordinal(); + } + + @Override + protected TableLabelProviderAdapter getTableLabelProvider() { + return new ServerDiskTableLabelProvider(); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerLogsPage.java new file mode 100644 index 00000000..a499caf3 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/ServerLogsPage.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ListViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.layout.FillLayout; +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.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class ServerLogsPage extends Composite { + + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private final GUIHelper guiHelper = GUIHelper.getInstance(); + private Text text; + private Table table; + + public enum LOG_TABLE_COLUMN_INDICES { + DATE, TIME, DISK, SEVERITY, MESSAGE + }; + + private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Disk", "Severity", "Message" }; + + /** + * Create the composite. + * + * @param parent + * @param style + */ + public ServerLogsPage(Composite parent, int style, GlusterServer server) { + super(parent, style); + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + setLayout(new GridLayout(1, false)); + GridData layoutData = new GridData(); + layoutData.grabExcessHorizontalSpace = true; + layoutData.grabExcessVerticalSpace = true; + setLayoutData(layoutData); + + Composite composite = toolkit.createComposite(this, SWT.NONE); + toolkit.paintBordersFor(composite); + + Label lblScanLast = toolkit.createLabel(composite, "Scan last", SWT.NONE); + lblScanLast.setBounds(0, 15, 80, 20); + + text = toolkit.createText(composite, "100", SWT.NONE); + text.setBounds(85, 15, 60, 20); + + Label lblMessagesAndFilter = toolkit.createLabel(composite, " messages from ", SWT.CENTER); + lblMessagesAndFilter.setBounds(160, 15, 110, 20); + + Combo combo = new Combo(composite, SWT.CENTER); + combo.setBounds(295, 15, 100, 20); + combo.setItems(new String[] { "syslog", "dmesg" }); + toolkit.adapt(combo); + toolkit.paintBordersFor(combo); + combo.select(0); + + Button btngo = toolkit.createButton(composite, "&Go", SWT.NONE); + btngo.setBounds(410, 13, 50, 30); + + Label separator = toolkit.createLabel(composite, "", SWT.SEPARATOR | SWT.HORIZONTAL | SWT.FILL); + separator.setBounds(0, 50, 500, 2); + + Label lblFilterString = toolkit.createLabel(composite, "Filter String", SWT.LEFT); + lblFilterString.setBounds(0, 65, 100, 20); + + text = guiHelper.createFilterText(toolkit, composite); + text.setBounds(105, 65, 250, 20); + + Composite logContentsComposite = createLogContentsComposite(toolkit); + // Text logContentsText = toolkit.createText(logContentsComposite, "", SWT.MULTI | SWT.FLAT | SWT.BORDER); + // logContentsText.setEditable(false); + // populateDummyLogContent(logContentsText); + + ListViewer logViewer = new ListViewer(logContentsComposite, SWT.BORDER | SWT.V_SCROLL | SWT.NO); + logViewer.setContentProvider(new ArrayContentProvider()); + guiHelper.createFilter(logViewer, text, false); + logViewer.setInput(getDummyLogContents()); + + // TODO: Link the filter string with the contents text + } + + private Composite createLogContentsComposite(FormToolkit toolkit) { + Composite tableViewerComposite = toolkit.createComposite(this, SWT.NONE); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 10; + tableViewerComposite.setLayoutData(layoutData); + return tableViewerComposite; + } + + private String[] getDummyLogContents() { + + String[] logMessages = { + "Jan 19 13:43:08 shireesh-laptop dhclient: last message repeated 6 times", + "Jan 19 13:44:08 shireesh-laptop dhclient: last message repeated 5 times", + "Jan 19 13:44:47 shireesh-laptop dhclient: last message repeated 2 times", + "Jan 19 13:44:47 shireesh-laptop dhclient: DHCPREQUEST of 192.168.1.174 on eth1 to 255.255.255.255 port 67", + "Jan 19 13:45:49 shireesh-laptop dhclient: last message repeated 6 times", + "Jan 19 13:46:59 shireesh-laptop dhclient: last message repeated 6 times", + "Jan 19 13:48:01 shireesh-laptop dhclient: last message repeated 4 times", + "Jan 19 13:49:02 shireesh-laptop dhclient: last message repeated 5 times", + "Jan 19 13:50:08 shireesh-laptop dhclient: last message repeated 4 times", + "Jan 19 13:51:08 shireesh-laptop dhclient: last message repeated 6 times", + "Jan 19 13:52:08 shireesh-laptop dhclient: last message repeated 4 times", + "Jan 19 13:53:08 shireesh-laptop dhclient: last message repeated 6 times", + "Jan 19 13:54:08 shireesh-laptop dhclient: last message repeated 5 times", + "Jan 19 13:55:08 shireesh-laptop dhclient: last message repeated 4 times", + "Jan 19 13:56:08 shireesh-laptop dhclient: last message repeated 4 times", + "Jan 19 13:57:08 shireesh-laptop dhclient: last message repeated 3 times", + "Jan 19 13:58:08 shireesh-laptop dhclient: last message repeated 6 times", + "Jan 19 13:59:08 shireesh-laptop dhclient: last message repeated 4 times", + "Jan 19 13:59:40 shireesh-laptop dhclient: last message repeated 3 times", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> DHCP: device eth1 state changed bound -> expire", + "Jan 19 13:59:40 shireesh-laptop dhclient: DHCPDISCOVER on eth1 to 255.255.255.255 port 67 interval 8", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> DHCP: device eth1 state changed expire -> preinit", + "Jan 19 13:59:40 shireesh-laptop dhclient: DHCPOFFER of 192.168.1.174 from 192.168.1.1", + "Jan 19 13:59:40 shireesh-laptop dhclient: DHCPREQUEST of 192.168.1.174 on eth1 to 255.255.255.255 port 67", + "Jan 19 13:59:40 shireesh-laptop dhclient: DHCPACK of 192.168.1.174 from 192.168.1.1", + "Jan 19 13:59:40 shireesh-laptop dhclient: bound to 192.168.1.174 -- renewal in 3205 seconds.", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> DHCP: device eth1 state changed preinit -> bound", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> address 192.168.1.174", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> prefix 24 (255.255.255.0)", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> gateway 192.168.1.1", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> nameserver '192.168.1.1'", + "Jan 19 13:59:40 shireesh-laptop NetworkManager: <info> domain name 'in.gluster.com'", + "Jan 19 14:03:53 shireesh-laptop avahi-daemon[1098]: Invalid legacy unicast query packet.", + "Jan 19 14:03:53 shireesh-laptop avahi-daemon[1098]: Received response from host 192.168.1.155 with invalid source port 37219 on interface 'eth0.0'", + "Jan 19 14:03:54 shireesh-laptop avahi-daemon[1098]: Invalid legacy unicast query packet.", + "Jan 19 14:03:54 shireesh-laptop avahi-daemon[1098]: Invalid legacy unicast query packet.", + "Jan 19 14:03:54 shireesh-laptop avahi-daemon[1098]: Received response from host 192.168.1.155 with invalid source port 37219 on interface 'eth0.0'", + "Jan 19 14:05:09 shireesh-laptop avahi-daemon[1098]: last message repeated 8 times", + "Jan 19 14:12:48 shireesh-laptop NetworkManager: <debug> [1295426568.002642] periodic_update(): Roamed from BSSID E0:CB:4E:C0:0B:7F (glfs) to (none) ((none))", + "Jan 19 14:12:54 shireesh-laptop NetworkManager: <debug> [1295426574.002448] periodic_update(): Roamed from BSSID (none) ((none)) to E0:CB:4E:C0:0B:7F (glfs)", + "Jan 19 14:17:01 shireesh-laptop CRON[5321]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)" }; + + return logMessages; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java new file mode 100644 index 00000000..1f5f8a15 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreator.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.Entity; + +/** + * For every entity that can be selected from the navigation view (cluster tree), a set of tabs are created on the + * details view. Each entity has a corresponding tab creator that creates these tabs. These tab creators must implement + * this interface. + * <p> + * <b>Important:</b> Tab creators are cached for performance reasons. Hence they should not store any state information + * in class level variables. + */ +public interface TabCreator { + /** + * Creates tabs for the given entity + * + * @param entity + * Entity for which tabs are to be created + * @param tabFolder + * The tab folder in which the tabs are to be created + * @param toolkit + * The form toolkit that can be used for create components using Forms API + * @param site + * The workbench site that can be used to register as a selection provider + */ + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site); +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java new file mode 100644 index 00000000..f5098af5 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactory.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import com.gluster.storage.management.core.model.Entity; + +/** + * Interface for tab creator factory. + */ +public interface TabCreatorFactory { + /** + * @param entity The entity for which tab creator factory is to be returned + * @return A tab creator factory for given entity + */ + public TabCreator getTabCreator(Entity entity); +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java new file mode 100644 index 00000000..28d3d4aa --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/TabCreatorFactoryImpl.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import java.util.HashMap; +import java.util.Map; + +import com.gluster.storage.management.core.exceptions.GlusterRuntimeException; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; + +public class TabCreatorFactoryImpl implements TabCreatorFactory { + + private Map<String, TabCreator> tabCreatorCache = new HashMap<String, TabCreator>(); + + /** + * Returns tab creator for given entity. The logic is as follows: <br> + * 1) Check if an tab creator is already created for the "class" of the entity. In case of {@link EntityGroup}, + * append the class name with entity type <br> + * 2) If the tab creator is found in the cache, return it <br> + * 3) If not found, create one by instantiating the class "<current package>.tabcreators.<class name>TabCreator". + * Again, "class name" includes "entity type" in case of {@link EntityGroup} <br> + * 4) Add the newly created tab creator to the cache and return it + */ + @SuppressWarnings("rawtypes") + @Override + public TabCreator getTabCreator(Entity entity) { + Class entityClass = entity.getClass(); + String key = entityClass.getSimpleName(); + if (entityClass == EntityGroup.class) { + // If it's an entity group, add the entity type to the key + key += ((EntityGroup) entity).getEntityType().getSimpleName(); + } + + TabCreator tabCreator = tabCreatorCache.get(key); + if (tabCreator == null) { + // Not created yet. Create one and add to the cache + String className = getClass().getPackage().getName() + ".tabcreators." + key + "TabCreator"; + try { + Class<TabCreator> creatorFactoryClass = (Class<TabCreator>) Class.forName(className); + tabCreator = creatorFactoryClass.newInstance(); + tabCreatorCache.put(key, tabCreator); + } catch (ClassNotFoundException e) { + throw new GlusterRuntimeException("Could not load creator factory class [" + className + "]", e); + } catch (InstantiationException e) { + throw new GlusterRuntimeException("Could not create instance of creator factory class [" + className + + "]", e); + } catch (IllegalAccessException e) { + throw new GlusterRuntimeException("Could not create instance of creator factory class [" + className + + "]", e); + } + } + + return tabCreator; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java new file mode 100644 index 00000000..d435201e --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeLogsPage.java @@ -0,0 +1,196 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.layout.FillLayout; +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.DateTime; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.GlusterDummyModel; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.VolumeLogTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class VolumeLogsPage extends Composite { + + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private final GUIHelper guiHelper = GUIHelper.getInstance(); + private Text text; + public enum LOG_TABLE_COLUMN_INDICES { + DATE, TIME, DISK, SEVERITY, MESSAGE + }; + + private static final String[] LOG_TABLE_COLUMN_NAMES = new String[] { "Date", "Time", "Disk", "Severity", "Message" }; + + /** + * Create the composite. + * @param parent + * @param style + */ + public VolumeLogsPage(Composite parent, int style, Volume volume) { + super(parent, style); + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + setLayout(new GridLayout(1, false)); + GridData layoutData = new GridData(); + layoutData.grabExcessHorizontalSpace = true; + layoutData.grabExcessVerticalSpace = true; + //layoutData.verticalIndent = 10; + setLayoutData(layoutData); + + Composite composite = toolkit.createComposite(this, SWT.NONE); + toolkit.paintBordersFor(composite); + + Label lblScanLast = toolkit.createLabel(composite, "Scan last", SWT.NONE); + lblScanLast.setBounds(0, 15, 80, 20); + + text = toolkit.createText(composite, "100", SWT.NONE); + text.setBounds(85, 15, 60, 20); + + Label lblMessagesAndFilter = toolkit.createLabel(composite, "messages, and filter on disk", SWT.NONE); + lblMessagesAndFilter.setBounds(160, 15, 200, 20); + + Combo combo = new Combo(composite, SWT.NONE); + combo.setBounds(365, 15, 100, 20); + combo.setItems(new String[] {"ALL", "sda", "sdb", "sdc", "sdd"}); + toolkit.adapt(combo); + toolkit.paintBordersFor(combo); + combo.select(0); + + Label lblSeverity = toolkit.createLabel(composite, "Severity", SWT.NONE); + lblSeverity.setBounds(480, 15, 70, 20); + + Combo combo_1 = new Combo(composite, SWT.NONE); + combo_1.setBounds(555, 15, 110, 20); + combo_1.setItems(new String[] {"ALL", "SEVERE", "WARNING", "DEBUG", "INFO"}); + toolkit.adapt(combo_1); + toolkit.paintBordersFor(combo_1); + combo_1.select(1); + + Label lblFrom = toolkit.createLabel(composite, "from", SWT.NONE); + lblFrom.setBounds(0, 60, 40, 20); + + DateTime dateTime = new DateTime(composite, SWT.BORDER | SWT.DROP_DOWN); + dateTime.setBounds(45, 60, 120, 20); + toolkit.adapt(dateTime); + toolkit.paintBordersFor(dateTime); + + DateTime dateTime_1 = new DateTime(composite, SWT.BORDER | SWT.TIME); + dateTime_1.setBounds(171, 60, 120, 20); + toolkit.adapt(dateTime_1); + toolkit.paintBordersFor(dateTime_1); + + Label lblTo = toolkit.createLabel(composite, "To", SWT.NONE); + lblTo.setBounds(329, 60, 26, 20); + + DateTime dateTime_2 = new DateTime(composite, SWT.BORDER | SWT.DROP_DOWN); + dateTime_2.setBounds(355, 60, 120, 20); + toolkit.adapt(dateTime_2); + toolkit.paintBordersFor(dateTime_2); + + DateTime dateTime_3 = new DateTime(composite, SWT.BORDER | SWT.TIME); + dateTime_3.setBounds(480, 60, 120, 20); + toolkit.adapt(dateTime_3); + toolkit.paintBordersFor(dateTime_3); + + Button btngo = toolkit.createButton(composite, "&Go", SWT.NONE); + btngo.setBounds(605, 55, 60, 30); + + Label separator = toolkit.createLabel(composite, "", SWT.SEPARATOR | SWT.HORIZONTAL | SWT.FILL); + separator.setBounds(0, 95, 680, 2); + + Label lblFilterString = toolkit.createLabel(composite, "Filter String", SWT.LEFT); + lblFilterString.setBounds(0, 105, 85, 20); + + text = guiHelper.createFilterText(toolkit, composite); + text.setBounds(90, 105, 250, 20); + + Composite tableViewerComposite = createTableViewerComposite(); + + TableViewer tableViewer = new TableViewer(tableViewerComposite, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new VolumeLogTableLabelProvider()); + tableViewer.setContentProvider(new ArrayContentProvider()); + + setupLogsTable(tableViewerComposite, tableViewer.getTable()); + guiHelper.createFilter(tableViewer, text, false); + tableViewer.setInput(GlusterDummyModel.getDummyLogMessages().toArray()); + } + + private Composite createTableViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true); + layoutData.verticalIndent = 10; + tableViewerComposite.setLayoutData(layoutData); + return tableViewerComposite; + } + + private void setupLogsTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, LOG_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.DATE, SWT.CENTER, 50); + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.TIME, SWT.CENTER, 50); + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.DISK, SWT.CENTER, 50); + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.SEVERITY, SWT.CENTER, 50); + setColumnProperties(table, LOG_TABLE_COLUMN_INDICES.MESSAGE, SWT.LEFT, 100); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + private void setColumnProperties(Table table, LOG_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java new file mode 100644 index 00000000..baa14a59 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/VolumeOptionsPage.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.VolumeOptionsTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class VolumeOptionsPage extends Composite { + + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private TableViewer tableViewer; + private GUIHelper guiHelper = GUIHelper.getInstance(); + + public enum OPTIONS_TABLE_COLUMN_INDICES { + OPTION_KEY, OPTION_VALUE + }; + + private static final String[] OPTIONS_TABLE_COLUMN_NAMES = new String[] { "Option Key", "Option Value" }; + + public VolumeOptionsPage(Composite parent, int style) { + super(parent, style); + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + setupPageLayout(); + Text filterText = guiHelper.createFilterText(toolkit, this); + setupDiskTableViewer(filterText); + } + + public VolumeOptionsPage(final Composite parent, int style, Volume volume) { + this(parent, style); + + tableViewer.setInput(volume.getOptions().entrySet().toArray()); + + parent.layout(); // Important - this actually paints the table + + /** + * Ideally not required. However the table viewer is not getting laid out properly on performing + * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window + */ + addPaintListener(new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + parent.layout(); + } + }); + + } + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(1, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + } + + private void setupDiskTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, OPTIONS_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, OPTIONS_TABLE_COLUMN_INDICES.OPTION_KEY, SWT.CENTER, 100); + setColumnProperties(table, OPTIONS_TABLE_COLUMN_INDICES.OPTION_VALUE, SWT.CENTER, 100); + } + + private TableViewer createDiskTableViewer(Composite parent) { + TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new VolumeOptionsTableLabelProvider()); + tableViewer.setContentProvider(new ArrayContentProvider()); + + setupDiskTable(parent, tableViewer.getTable()); + + return tableViewer; + } + + private Composite createTableViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return tableViewerComposite; + } + + private void setupDiskTableViewer(final Text filterText) { + Composite tableViewerComposite = createTableViewerComposite(); + tableViewer = createDiskTableViewer(tableViewerComposite); + // Create a case insensitive filter for the table viewer using the filter text field + guiHelper.createFilter(tableViewer, filterText, false); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, OPTIONS_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/ClusterTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/ClusterTabCreator.java new file mode 100644 index 00000000..571afb2e --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/ClusterTabCreator.java @@ -0,0 +1,146 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ImageHyperlink; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.TabCreator; + +public class ClusterTabCreator implements TabCreator { + private GUIHelper guiHelper = GUIHelper.getInstance(); + + private int getVolumeCountByStatus(Cluster cluster, VOLUME_STATUS status) { + int count = 0; + for (Volume volume : cluster.getVolumes()) { + if (volume.getStatus() == status) { + count++; + } + } + return count; + } + + private int getServerCountByStatus(Cluster cluster, SERVER_STATUS status) { + int count = 0; + for (GlusterServer server : cluster.getServers()) { + if (server.getStatus() == status) { + count++; + } + } + return count; + } + + private void createVolumesSection(Cluster cluster, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Volumes", null, 1, false); + + // toolkit.createLabel(sectionClient, "Number of Volumes: ", SWT.NONE); + // toolkit.createLabel(sectionClient, "12", SWT.NONE); + // + // toolkit.createLabel(sectionClient, "Online: ", SWT.NONE); + // Label labelOnlineCount = toolkit.createLabel(sectionClient, "9", SWT.NONE); + // labelOnlineCount.setForeground(SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN)); + // + // toolkit.createLabel(sectionClient, "Offline: ", SWT.NONE); + // Label lblOfflineCount = toolkit.createLabel(sectionClient, "3", SWT.NONE); + // lblOfflineCount.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED)); + + Double[] values = new Double[] { Double.valueOf(getVolumeCountByStatus(cluster, VOLUME_STATUS.ONLINE)), + Double.valueOf(getVolumeCountByStatus(cluster, VOLUME_STATUS.OFFLINE)) }; + createStatusChart(toolkit, section, values); + } + + private void createServersSection(Cluster cluster, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Servers", null, 1, false); + +// toolkit.createLabel(sectionClient, "Number of Servers: ", SWT.NONE); +// toolkit.createLabel(sectionClient, "7", SWT.NONE); +// +// toolkit.createLabel(sectionClient, "Online: ", SWT.NONE); +// Label labelOnlineCount = toolkit.createLabel(sectionClient, "6", SWT.NONE); +// labelOnlineCount.setForeground(SWTResourceManager.getColor(SWT.COLOR_DARK_GREEN)); +// +// toolkit.createLabel(sectionClient, "Offline: ", SWT.NONE); +// Label lblOfflineCount = toolkit.createLabel(sectionClient, "1", SWT.NONE); +// lblOfflineCount.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED)); + + Double[] values = new Double[] { Double.valueOf(getServerCountByStatus(cluster, SERVER_STATUS.ONLINE)), + Double.valueOf(getServerCountByStatus(cluster, SERVER_STATUS.OFFLINE)) }; + + createStatusChart(toolkit, section, values); + } + + private void createStatusChart(FormToolkit toolkit, Composite section, Double[] values) { + String[] categories = new String[] { "Online", "Offline" }; + PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, values); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = 250; + data.heightHint = 250; + chartViewerComposite.setLayoutData(data); + } + + private void createActionsSection(final Cluster cluster, final FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Actions", null, 1, false); + + ImageHyperlink imageHyperlink = toolkit.createImageHyperlink(section, SWT.NONE); + imageHyperlink.setText("Create Volume"); + imageHyperlink.setImage(guiHelper.getImage(IImageKeys.CREATE_VOLUME_BIG)); + imageHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + // TODO: Override appropriate method and handle hyperlink event + }); + + imageHyperlink = toolkit.createImageHyperlink(section, SWT.NONE); + imageHyperlink.setText("Add Server(s)"); + imageHyperlink.setImage(guiHelper.getImage(IImageKeys.ADD_SERVER_BIG)); + imageHyperlink.addHyperlinkListener(new HyperlinkAdapter() { + // TODO: Override appropriate method and handle hyperlink event + }); + } + + private void createClusterSummaryTab(final Cluster cluster, final TabFolder tabFolder, final FormToolkit toolkit) { + Composite summaryTab = guiHelper.createTab(tabFolder, cluster.getName(), IImageKeys.CLUSTER); + + final ScrolledForm form = guiHelper.setupForm(summaryTab, toolkit, "Cluster Summary"); + createVolumesSection(cluster, toolkit, form); + createServersSection(cluster, toolkit, form); + createActionsSection(cluster, toolkit, form); + + summaryTab.layout(); // IMP: lays out the form properly + } + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + createClusterSummaryTab((Cluster) entity, tabFolder, toolkit); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupGlusterServerTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupGlusterServerTabCreator.java new file mode 100644 index 00000000..3c94c3cc --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupGlusterServerTabCreator.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import com.gluster.storage.management.core.model.Disk; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.NavigationView; +import com.gluster.storage.management.gui.views.details.DisksPage; +import com.gluster.storage.management.gui.views.details.GlusterServersPage; +import com.gluster.storage.management.gui.views.details.TabCreator; + +public class EntityGroupGlusterServerTabCreator implements TabCreator, IDoubleClickListener { + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + private int getServerCountByStatus(EntityGroup<GlusterServer> servers, SERVER_STATUS status) { + int count = 0; + for (GlusterServer server : (List<GlusterServer>)servers.getEntities()) { + if (server.getStatus() == status) { + count++; + } + } + return count; + } + + private void createAlertsSection(final EntityGroup<GlusterServer> servers, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 2, false); + + toolkit.createLabel(section, "Any alerts related to servers\nwill be displayed here."); + } + + private void createRunningTasksSection(final EntityGroup<GlusterServer> servers, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Running Tasks", null, 2, false); + + toolkit.createLabel(section, "List of running tasks related to\nservers will be displayed here."); + } + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + createSummaryTab((EntityGroup<GlusterServer>)entity, tabFolder, toolkit); + createServersTab((EntityGroup<GlusterServer>)entity, tabFolder, toolkit); + createDisksTab((EntityGroup<GlusterServer>)entity, tabFolder, toolkit, site); + } + + private void createServersTab(EntityGroup<GlusterServer> servers, TabFolder tabFolder, FormToolkit toolkit) { + Composite serversTab = guiHelper.createTab(tabFolder, "Servers", IImageKeys.SERVERS); + GlusterServersPage page = new GlusterServersPage(serversTab, SWT.NONE, servers); + page.addDoubleClickListener(this); + } + + private void createSummaryTab(EntityGroup<GlusterServer> servers, TabFolder tabFolder, FormToolkit toolkit) { + Composite summaryTab = guiHelper.createTab(tabFolder, "Summary", IImageKeys.SERVERS); + final ScrolledForm form = guiHelper.setupForm(summaryTab, toolkit, "Servers - Summary"); + createSummarySection(servers, toolkit, form); + createRunningTasksSection(servers, toolkit, form); + createAlertsSection(servers, toolkit, form); + + summaryTab.layout(); // IMP: lays out the form properly + } + + private void createSummarySection(final EntityGroup<GlusterServer> servers, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Availability", null, 2, false); + + Double[] values = new Double[] { Double.valueOf(getServerCountByStatus(servers, SERVER_STATUS.ONLINE)), + Double.valueOf(getServerCountByStatus(servers, SERVER_STATUS.OFFLINE)) }; + createStatusChart(toolkit, section, values); + } + + private void createStatusChart(FormToolkit toolkit, Composite section, Double[] values) { + String[] categories = new String[] { "Online", "Offline" }; + PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, values); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = 250; + data.heightHint = 250; + chartViewerComposite.setLayoutData(data); + } + + + private void createDisksTab(EntityGroup<GlusterServer> servers, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + Composite disksTab = guiHelper.createTab(tabFolder, "Disks", IImageKeys.SERVERS); + DisksPage page = new DisksPage(disksTab, SWT.NONE, site, getAllDisks(servers)); + + disksTab.layout(); // IMP: lays out the form properly + } + + private List<Disk> getAllDisks(EntityGroup<GlusterServer> servers) { + List<Disk> disks = new ArrayList<Disk>(); + for(GlusterServer server : (List<GlusterServer>)servers.getEntities()) { + disks.addAll(server.getDisks()); + } + return disks; + } + + @Override + public void doubleClick(DoubleClickEvent event) { + NavigationView clusterView = (NavigationView) guiHelper.getView(NavigationView.ID); + if (clusterView != null) { + clusterView.selectEntity((Entity) ((StructuredSelection) event.getSelection()).getFirstElement()); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupServerTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupServerTabCreator.java new file mode 100644 index 00000000..3f49ba6b --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupServerTabCreator.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.NavigationView; +import com.gluster.storage.management.gui.views.details.TabCreator; +import com.gluster.storage.management.gui.views.pages.ServersPage; + +public class EntityGroupServerTabCreator implements TabCreator, IDoubleClickListener { + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + createServersTab((EntityGroup<Server>) entity, tabFolder); + } + + private void createServersTab(EntityGroup<Server> servers, TabFolder tabFolder) { + Composite serversTab = guiHelper.createTab(tabFolder, "Discovered Servers", IImageKeys.SERVERS); + ServersPage page = new ServersPage(serversTab, null, servers); + page.addDoubleClickListener(this); + } + + @Override + public void doubleClick(DoubleClickEvent event) { + NavigationView clusterView = (NavigationView) guiHelper.getView(NavigationView.ID); + if (clusterView != null) { + clusterView.selectEntity((Entity) ((StructuredSelection) event.getSelection()).getFirstElement()); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupVolumeTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupVolumeTabCreator.java new file mode 100644 index 00000000..22ffd94d --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/EntityGroupVolumeTabCreator.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import java.util.List; + +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.VOLUME_STATUS; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.NavigationView; +import com.gluster.storage.management.gui.views.details.TabCreator; +import com.gluster.storage.management.gui.views.pages.VolumesPage; + +public class EntityGroupVolumeTabCreator implements TabCreator, IDoubleClickListener { + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + createSummaryTab((EntityGroup<Volume>) entity, tabFolder, toolkit); + createVolumesTab((EntityGroup<Volume>) entity, tabFolder, toolkit); + } + + private int getVolumeCountByStatus(EntityGroup<Volume> volumes, VOLUME_STATUS status) { + int count = 0; + for (Volume volume : (List<Volume>) volumes.getEntities()) { + if (volume.getStatus() == status) { + count++; + } + } + return count; + } + + private void createStatusChart(FormToolkit toolkit, Composite section, Double[] values) { + String[] categories = new String[] { "Online", "Offline" }; + PieChartViewerComposite chartViewerComposite = new PieChartViewerComposite(section, SWT.NONE, categories, + values); + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.widthHint = 250; + data.heightHint = 250; + chartViewerComposite.setLayoutData(data); + } + + private void createAlertsSection(final EntityGroup<Volume> volumes, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 2, false); + + toolkit.createLabel(section, "Any alerts related to volumes\nwill be displayed here."); + } + + private void createRunningTasksSection(final EntityGroup<Volume> volumes, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Running Tasks", null, 2, false); + + toolkit.createLabel(section, "List of running tasks related to\nvolumes will be displayed here."); + } + + private void createSummarySection(final EntityGroup<Volume> volumes, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Availability", null, 2, false); + + Double[] values = new Double[] { Double.valueOf(getVolumeCountByStatus(volumes, VOLUME_STATUS.ONLINE)), + Double.valueOf(getVolumeCountByStatus(volumes, VOLUME_STATUS.OFFLINE)) }; + createStatusChart(toolkit, section, values); + } + + private void createSummaryTab(final EntityGroup<Volume> volumes, TabFolder tabFolder, FormToolkit toolkit) { + Composite summaryTab = guiHelper.createTab(tabFolder, "Summary", IImageKeys.VOLUMES); + final ScrolledForm form = guiHelper.setupForm(summaryTab, toolkit, "Volumes - Summary"); + createSummarySection(volumes, toolkit, form); + createRunningTasksSection(volumes, toolkit, form); + createAlertsSection(volumes, toolkit, form); + + summaryTab.layout(); // IMP: lays out the form properly + } + + private void createVolumesTab(EntityGroup<Volume> volumes, TabFolder tabFolder, FormToolkit toolkit) { + Composite volumesTab = guiHelper.createTab(tabFolder, "Volumes", IImageKeys.VOLUMES); + VolumesPage page = new VolumesPage(volumesTab, null, volumes); + page.addDoubleClickListener(this); + } + + @Override + public void doubleClick(DoubleClickEvent event) { + NavigationView clusterView = (NavigationView) guiHelper.getView(NavigationView.ID); + if (clusterView != null) { + clusterView.selectEntity((Entity) ((StructuredSelection) event.getSelection()).getFirstElement()); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/GlusterServerTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/GlusterServerTabCreator.java new file mode 100644 index 00000000..e1aa59ff --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/GlusterServerTabCreator.java @@ -0,0 +1,261 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.ProgressBar; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.GlusterServer.SERVER_STATUS; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.NetworkInterfaceTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.ServerDisksPage; +import com.gluster.storage.management.gui.views.details.ServerLogsPage; +import com.gluster.storage.management.gui.views.details.TabCreator; +import com.richclientgui.toolbox.gauges.CoolGauge; + +public class GlusterServerTabCreator implements TabCreator { + public enum NETWORK_INTERFACE_TABLE_COLUMN_INDICES { + INTERFACE, IP_ADDRESS, NETMASK, GATEWAY + }; + + private static final String[] NETWORK_INTERFACE_TABLE_COLUMN_NAMES = { "Interface", "IP Address", "Netmask", + "Gateway" }; + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + private void createServerSummarySection(GlusterServer server, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Summary", null, 2, false); + +// toolkit.createLabel(section, "Preferred Network: ", SWT.NONE); +// toolkit.createLabel(section, server.getPreferredNetworkInterface().getName(), SWT.NONE); + + boolean online = server.getStatus() == SERVER_STATUS.ONLINE; + + if (online) { + toolkit.createLabel(section, "Number of CPUs: ", SWT.NONE); + toolkit.createLabel(section, "" + server.getNumOfCPUs(), SWT.NONE); + + // toolkit.createLabel(section, "CPU Usage (%): ", SWT.NONE); + // toolkit.createLabel(section, online ? "" + server.getCpuUsage() : "NA", SWT.NONE); + + toolkit.createLabel(section, "% CPU Usage (avg): ", SWT.NONE); + CoolGauge gauge = new CoolGauge(section, guiHelper.getImage(IImageKeys.GAUGE_SMALL)); + gauge.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false)); + gauge.setGaugeNeedleColour(Display.getDefault().getSystemColor(SWT.COLOR_RED)); + gauge.setGaugeNeedleWidth(2); + gauge.setGaugeNeedlePivot(new Point(66, 65)); + + gauge.setPoints(getPnts()); + gauge.setLevel(server.getCpuUsage() / 100); + gauge.setToolTipText(server.getCpuUsage() + "%"); + + toolkit.createLabel(section, "Memory Usage: ", SWT.NONE); + ProgressBar memoryUsageBar = new ProgressBar(section, SWT.SMOOTH); + memoryUsageBar.setMinimum(0); + memoryUsageBar.setMaximum((int) Math.round(server.getTotalMemory())); + memoryUsageBar.setSelection((int) Math.round(server.getMemoryInUse())); + memoryUsageBar.setToolTipText("Total: " + server.getTotalMemory() + "GB, In Use: " + + server.getMemoryInUse() + "GB"); + + // toolkit.createLabel(section, "Memory Usage: ", SWT.NONE); + // final CoolProgressBar bar = new CoolProgressBar(section,SWT.HORIZONTAL, + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_LEFT), + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_FILLED), + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_EMPTY), + // guiHelper.getImage(IImageKeys.PROGRESS_BAR_RIGHT)); + // bar.updateProgress(server.getMemoryInUse() / server.getTotalMemory()); + + // toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + // toolkit.createLabel(section, online ? "" + server.getTotalDiskSpace() : "NA", SWT.NONE); + // + // toolkit.createLabel(section, "Disk Space in Use (GB): ", SWT.NONE); + // toolkit.createLabel(section, online ? "" + server.getDiskSpaceInUse() : "NA", SWT.NONE); + + toolkit.createLabel(section, "Disk Usage: ", SWT.NONE); + ProgressBar diskUsageBar = new ProgressBar(section, SWT.SMOOTH); + diskUsageBar.setMinimum(0); + diskUsageBar.setMaximum((int) Math.round(server.getTotalDiskSpace())); + diskUsageBar.setSelection((int) Math.round(server.getDiskSpaceInUse())); + diskUsageBar.setToolTipText("Total: " + NumberUtil.formatNumber(server.getTotalDiskSpace()) + + "GB, In Use: " + NumberUtil.formatNumber(server.getDiskSpaceInUse()) + "GB"); + } + + toolkit.createLabel(section, "Status: ", SWT.NONE); + CLabel lblStatusValue = new CLabel(section, SWT.NONE); + lblStatusValue.setText(server.getStatusStr()); + lblStatusValue.setImage(server.getStatus() == GlusterServer.SERVER_STATUS.ONLINE ? guiHelper + .getImage(IImageKeys.STATUS_ONLINE) : guiHelper.getImage(IImageKeys.STATUS_OFFLINE)); + toolkit.adapt(lblStatusValue, true, true); + } + + private List<Point> getPnts() { + final List<Point> pnts = new ArrayList<Point>(); + pnts.add(new Point(47, 98)); + pnts.add(new Point(34, 84)); + pnts.add(new Point(29, 65)); + pnts.add(new Point(33, 48)); + pnts.add(new Point(48, 33)); + pnts.add(new Point(66, 28)); + pnts.add(new Point(83, 32)); + pnts.add(new Point(98, 47)); + pnts.add(new Point(103, 65)); + pnts.add(new Point(98, 83)); + pnts.add(new Point(84, 98)); + return pnts; + } + + private void createServerSummaryTab(GlusterServer server, TabFolder tabFolder, FormToolkit toolkit) { + String serverName = server.getName(); + Composite serverSummaryTab = guiHelper.createTab(tabFolder, serverName, IImageKeys.SERVER); + final ScrolledForm form = guiHelper.setupForm(serverSummaryTab, toolkit, "Server Summary [" + serverName + "]"); + createServerSummarySection(server, toolkit, form); + + if (server.getStatus() == SERVER_STATUS.ONLINE) { + Composite section = createNetworkInterfacesSection(server, toolkit, form); + } + + serverSummaryTab.layout(); // IMP: lays out the form properly + } + + private void setupNetworkInterfaceTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, + NETWORK_INTERFACE_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.INTERFACE, SWT.CENTER, 70); + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.IP_ADDRESS, SWT.CENTER, 100); + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.NETMASK, SWT.CENTER, 70); + setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.GATEWAY, SWT.CENTER, 70); + // setColumnProperties(table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES.PREFERRED, SWT.CENTER, 70); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, NETWORK_INTERFACE_TABLE_COLUMN_INDICES columnIndex, int alignment, + int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } + + private TableViewer createNetworkInterfacesTableViewer(final Composite parent, GlusterServer server) { + TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new NetworkInterfaceTableLabelProvider()); + tableViewer.setContentProvider(new ArrayContentProvider()); + + setupNetworkInterfaceTable(parent, tableViewer.getTable()); + tableViewer.setInput(server.getNetworkInterfaces().toArray()); + + return tableViewer; + } + + private Composite createTableViewerComposite(Composite parent) { + Composite tableViewerComposite = new Composite(parent, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + GridData tableLayoutData = new GridData(SWT.FILL, SWT.FILL, true, false); + tableLayoutData.widthHint = 400; + tableLayoutData.minimumWidth = 400; + // tableLayoutData.grabExcessHorizontalSpace = true; + tableViewerComposite.setLayoutData(tableLayoutData); + return tableViewerComposite; + } + + private Composite createNetworkInterfacesSection(GlusterServer server, FormToolkit toolkit, ScrolledForm form) { + final Composite section = guiHelper.createSection(form, toolkit, "Network Interfaces", null, 1, false); + createNetworkInterfacesTableViewer(createTableViewerComposite(section), server); +// Hyperlink changePreferredNetworkLink = toolkit.createHyperlink(section, "Change Preferred Network", SWT.NONE); +// changePreferredNetworkLink.addHyperlinkListener(new HyperlinkAdapter() { +// +// @Override +// public void linkActivated(HyperlinkEvent e) { +// new MessageDialog( +// section.getShell(), +// "Gluster Storage Platform", +// guiHelper.getImage(IImageKeys.SERVER), +// "This will show additional controls to help user choose a new network interface. TO BE IMPLEMENTED.", +// MessageDialog.INFORMATION, new String[] { "OK" }, 0).open(); +// } +// }); + return section; + } + + private void createServerLogsTab(GlusterServer server, TabFolder tabFolder, FormToolkit toolkit) { + String serverName = server.getName(); + Composite serverLogsTab = guiHelper.createTab(tabFolder, "Logs", IImageKeys.SERVER); + ServerLogsPage logsPage = new ServerLogsPage(serverLogsTab, SWT.NONE, server); + + serverLogsTab.layout(); // IMP: lays out the form properly + } + + private void createServerDisksTab(GlusterServer server, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + Composite serverDisksTab = guiHelper.createTab(tabFolder, "Disks", IImageKeys.SERVER); + ServerDisksPage page = new ServerDisksPage(serverDisksTab, SWT.NONE, site, server.getDisks()); + + serverDisksTab.layout(); // IMP: lays out the form properly + } + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + GlusterServer server = (GlusterServer) entity; + + createServerSummaryTab(server, tabFolder, toolkit); + if (server.getStatus() == SERVER_STATUS.ONLINE) { + createServerDisksTab(server, tabFolder, toolkit, site); + createServerLogsTab(server, tabFolder, toolkit); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/PieChartViewerComposite.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/PieChartViewerComposite.java new file mode 100644 index 00000000..80c9c807 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/PieChartViewerComposite.java @@ -0,0 +1,254 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.eclipse.birt.chart.api.ChartEngine; +import org.eclipse.birt.chart.device.IDeviceRenderer; +import org.eclipse.birt.chart.device.IUpdateNotifier; +import org.eclipse.birt.chart.exception.ChartException; +import org.eclipse.birt.chart.factory.GeneratedChartState; +import org.eclipse.birt.chart.factory.Generator; +import org.eclipse.birt.chart.model.Chart; +import org.eclipse.birt.chart.model.ChartWithoutAxes; +import org.eclipse.birt.chart.model.attribute.Bounds; +import org.eclipse.birt.chart.model.attribute.ChartDimension; +import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl; +import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl; +import org.eclipse.birt.chart.model.component.Series; +import org.eclipse.birt.chart.model.component.impl.SeriesImpl; +import org.eclipse.birt.chart.model.data.NumberDataSet; +import org.eclipse.birt.chart.model.data.SeriesDefinition; +import org.eclipse.birt.chart.model.data.TextDataSet; +import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl; +import org.eclipse.birt.chart.model.data.impl.SeriesDefinitionImpl; +import org.eclipse.birt.chart.model.data.impl.TextDataSetImpl; +import org.eclipse.birt.chart.model.impl.ChartWithoutAxesImpl; +import org.eclipse.birt.chart.model.layout.Legend; +import org.eclipse.birt.chart.model.layout.Plot; +import org.eclipse.birt.chart.model.type.PieSeries; +import org.eclipse.birt.chart.model.type.impl.PieSeriesImpl; +import org.eclipse.birt.core.framework.PlatformConfig; +import org.eclipse.core.runtime.Platform; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.ControlListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; + +/** + * + */ +public final class PieChartViewerComposite extends Composite implements + PaintListener, IUpdateNotifier { + + private IDeviceRenderer deviceReader = null; + private Chart chart = null; + private GeneratedChartState generatedChartState = null; + private boolean needsGeneration = true; + + private static Logger logger = Logger + .getLogger(PieChartViewerComposite.class.getName()); + + /** + * @param parent + * Parent composite of this pie chart viewer composite + * @param style + * SWT style to be used + * @param categories + * Categories of the pie chart + * @param values + * Values of each category in the pie chart Constructs a pie + * chart viewer composite for given categories and values + */ + public PieChartViewerComposite(Composite parent, int style, String[] categories, + Double[] values) { + super(parent, style); + try { + PlatformConfig config = new PlatformConfig(); + config.setBIRTHome(Platform.getInstallLocation().getURL().getPath()); + // Get the connection with SWT device to render the graphics. + deviceReader = ChartEngine.instance(config).getRenderer("dv.SWT");//$NON-NLS-1$ + } catch (ChartException ex) { + logger.log(Level.SEVERE, "Could not create Chart Renderer for SWT", + ex); + } + + addControlListener(new ControlListener() { + + public void controlMoved(ControlEvent e) { + needsGeneration = true; + } + + public void controlResized(ControlEvent e) { + needsGeneration = true; + } + }); + + chart = createPieChart(categories, values); + addPaintListener(this); + } + + /** + * @param categories + * Categories of the pie chart + * @param values + * Values of each category in the pie chart + * @return The chart object created for given categories and values + */ + public static final Chart createPieChart(String[] categories, + Double[] values) { + ChartWithoutAxes pieChart = ChartWithoutAxesImpl.create(); + + // Plot + pieChart.setSeriesThickness(2); + pieChart.setDimension(ChartDimension.TWO_DIMENSIONAL_WITH_DEPTH_LITERAL); + pieChart.getBlock().setBackground(ColorDefinitionImpl.WHITE()); + Plot p = pieChart.getPlot(); + p.getClientArea().setBackground(null); + p.getClientArea().getOutline().setVisible(false); + p.getOutline().setVisible(false); + + // Legend + Legend lg = pieChart.getLegend(); + lg.getText().getFont().setSize(8); + lg.setBackground(null); + lg.getOutline().setVisible(false); + lg.setVisible(true); + + // Title + pieChart.getTitle().getLabel().getCaption().setValue("Pie Chart");//$NON-NLS-1$ + pieChart.getTitle().getOutline().setVisible(false); + pieChart.getTitle().setVisible(false); + + TextDataSet categoryValues = TextDataSetImpl.create(categories); + NumberDataSet seriesOneValues = NumberDataSetImpl.create(values); + + // Base Series + Series seCategory = SeriesImpl.create(); + seCategory.setDataSet(categoryValues); + + SeriesDefinition sd = SeriesDefinitionImpl.create(); + pieChart.getSeriesDefinitions().add(sd); + sd.getSeriesPalette().shift(0); + sd.getSeries().add(seCategory); + + // Orthogonal Series + PieSeries sePie = (PieSeries) PieSeriesImpl.create(); + sePie.setDataSet(seriesOneValues); + sePie.setSeriesIdentifier("Cities");//$NON-NLS-1$ + sePie.getTitle().setVisible(false); + sePie.setExplosion(2); + + SeriesDefinition seriesDefinition = SeriesDefinitionImpl.create(); + seriesDefinition.getQuery().setDefinition("query.definition");//$NON-NLS-1$ + sd.getSeriesDefinitions().add(seriesDefinition); + seriesDefinition.getSeries().add(sePie); + + return pieChart; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events + * .PaintEvent) + */ + public final void paintControl(PaintEvent e) { + Rectangle d = ((Composite) e.getSource()).getBounds(); + Image imgChart = new Image(this.getDisplay(), d); + GC gcImage = new GC(imgChart); + deviceReader.setProperty(IDeviceRenderer.GRAPHICS_CONTEXT, gcImage); + deviceReader.setProperty(IDeviceRenderer.UPDATE_NOTIFIER, this); + + Bounds bo = BoundsImpl.create(0, 0, d.width, d.height); + bo.scale(58d / deviceReader.getDisplayServer().getDpiResolution()); + + Generator gr = Generator.instance(); + if (needsGeneration) { + needsGeneration = false; + try { + generatedChartState = gr.build(deviceReader.getDisplayServer(), + chart, bo, null, null, null); + } catch (ChartException ce) { + ce.printStackTrace(); + } + } + + try { + gr.render(deviceReader, generatedChartState); + GC gc = e.gc; + gc.drawImage(imgChart, d.x, d.y); + } catch (ChartException gex) { + logger.log(Level.SEVERE, "Exception while rendering pie chart [" + + gex.getMessage() + "]", gex); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#getDesignTimeModel() + */ + public Chart getDesignTimeModel() { + return chart; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#getRunTimeModel() + */ + public Chart getRunTimeModel() { + return generatedChartState.getChartModel(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#peerInstance() + */ + public Object peerInstance() { + return this; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#regenerateChart() + */ + public void regenerateChart() { + redraw(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.birt.chart.device.IUpdateNotifier#repaintChart() + */ + public void repaintChart() { + redraw(); + } +}
\ No newline at end of file diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/ServerTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/ServerTabCreator.java new file mode 100644 index 00000000..d634253e --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/ServerTabCreator.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.TabCreator; + +public class ServerTabCreator implements TabCreator { + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + private void createServerSummarySection(Server server, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Summary", null, 2, false); + + toolkit.createLabel(section, "Number of CPUs: ", SWT.NONE); + toolkit.createLabel(section, "" + server.getNumOfCPUs(), SWT.NONE); + +// toolkit.createLabel(section, "CPU Usage (%): ", SWT.NONE); +// toolkit.createLabel(section, "" + server.getCpuUsage(), SWT.NONE); + + toolkit.createLabel(section, "Total Memory (GB): ", SWT.NONE); + toolkit.createLabel(section, "" + server.getTotalMemory(), SWT.NONE); + +// toolkit.createLabel(section, "Memory in Use (GB): ", SWT.NONE); +// toolkit.createLabel(section, "" + server.getMemoryInUse(), SWT.NONE); + + toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + toolkit.createLabel(section, "" + NumberUtil.formatNumber(server.getTotalDiskSpace()), SWT.NONE); + +// toolkit.createLabel(section, "Disk Space in Use (GB): ", SWT.NONE); +// toolkit.createLabel(section, "" + server.getDiskSpaceInUse(), SWT.NONE); + } + + private void createServerSummaryTab(Server server, TabFolder tabFolder, FormToolkit toolkit) { + String serverName = server.getName(); + Composite serverSummaryTab = guiHelper.createTab(tabFolder, serverName, IImageKeys.SERVER); + final ScrolledForm form = guiHelper.setupForm(serverSummaryTab, toolkit, "Discovered Server Summary [" + serverName + "]"); + createServerSummarySection(server, toolkit, form); + + serverSummaryTab.layout(); // IMP: lays out the form properly + } + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + createServerSummaryTab((Server) entity, tabFolder, toolkit); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/VolumeTabCreator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/VolumeTabCreator.java new file mode 100644 index 00000000..3e5382cc --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/details/tabcreators/VolumeTabCreator.java @@ -0,0 +1,269 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.details.tabcreators; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.TabFolder; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.events.HyperlinkAdapter; +import org.eclipse.ui.forms.events.HyperlinkEvent; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.forms.widgets.Hyperlink; +import org.eclipse.ui.forms.widgets.ScrolledForm; + +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.core.model.Volume.NAS_PROTOCOL; +import com.gluster.storage.management.core.model.Volume.VOLUME_TYPE; +import com.gluster.storage.management.core.utils.NumberUtil; +import com.gluster.storage.management.gui.IImageKeys; +import com.gluster.storage.management.gui.utils.GUIHelper; +import com.gluster.storage.management.gui.views.details.DisksPage; +import com.gluster.storage.management.gui.views.details.TabCreator; +import com.gluster.storage.management.gui.views.details.VolumeLogsPage; +import com.gluster.storage.management.gui.views.details.VolumeOptionsPage; + +public class VolumeTabCreator implements TabCreator { + private static final GUIHelper guiHelper = GUIHelper.getInstance(); + + private void createVolumePropertiesSection(final Volume volume, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Properties", null, 3, false); + + createVolumeTypeField(volume, toolkit, section); + + VOLUME_TYPE volumeType = volume.getVolumeType(); + if (volumeType == VOLUME_TYPE.DISTRIBUTED_MIRROR) { + createReplicaCountField(volume, toolkit, section); + } + + if (volumeType == VOLUME_TYPE.DISTRIBUTED_STRIPE) { + createStripeCountField(volume, toolkit, section); + } + + createNumOfDisksField(volume, toolkit, section); + createDiskSpaceField(volume, toolkit, section); + createTransportTypeField(volume, toolkit, section); + createNASProtocolField(volume, toolkit, section); + createAccessControlField(volume, toolkit, section); + createStatusField(volume, toolkit, section); + } + + private void createDiskSpaceField(final Volume volume, FormToolkit toolkit, Composite section) { + Label diskSpaceLabel = toolkit.createLabel(section, "Total Disk Space (GB): ", SWT.NONE); + diskSpaceLabel.setToolTipText("<b>bold</b>normal"); + toolkit.createLabel(section, "" + NumberUtil.formatNumber(volume.getTotalDiskSpace()), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createStatusField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Status: ", SWT.NONE); + + CLabel lblStatusValue = new CLabel(section, SWT.NONE); + lblStatusValue.setText(volume.getStatusStr()); + lblStatusValue.setImage(volume.getStatus() == Volume.VOLUME_STATUS.ONLINE ? guiHelper + .getImage(IImageKeys.STATUS_ONLINE) : guiHelper.getImage(IImageKeys.STATUS_OFFLINE)); + + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createTransportTypeField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Transport Type: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getTransportTypeStr(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createNumOfDisksField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Number of Disks: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getNumOfDisks(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createStripeCountField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Stripe Count: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getStripeCount(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createReplicaCountField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Replica Count: ", SWT.NONE); + toolkit.createLabel(section, "" + volume.getReplicaCount(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); // dummy + } + + private void createVolumeTypeField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Volume Type: ", SWT.NONE); + toolkit.createLabel(section, volume.getVolumeTypeStr(), SWT.NONE); + toolkit.createLabel(section, "", SWT.NONE); + } + + private void createVolumeAlertsSection(final Volume volume, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Alerts", null, 3, false); + toolkit.createLabel(section, "Volume related alerts will be displayed here"); + } + + private void createVolumeMountingInfoSection(final Volume volume, FormToolkit toolkit, final ScrolledForm form) { + Composite section = guiHelper.createSection(form, toolkit, "Mounting Information", null, 3, false); + toolkit.createLabel(section, "Information about mounting the\nvolume will be printed here"); + } + + private GridData createDefaultLayoutData() { + GridData layoutData = new GridData(); + layoutData.minimumWidth = 150; + layoutData.widthHint = 150; + return layoutData; + } + + private void createAccessControlField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "Access Control: ", SWT.NONE); + Text accessControlText = toolkit.createText(section, volume.getAccessControlList()); + accessControlText.setLayoutData(createDefaultLayoutData()); + accessControlText.setEnabled(false); + createChangeLinkForAccessControl(volume, toolkit, section, accessControlText); + } + + private void createChangeLinkForAccessControl(final Volume volume, FormToolkit toolkit, Composite section, + final Text accessControlText) { + final Hyperlink changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); + changeLink.addHyperlinkListener(new HyperlinkAdapter() { + + private void finishEdit() { + // TODO: Update value to back-end + // TODO: Validation of entered text + volume.setAccessControlList(accessControlText.getText()); + accessControlText.setEnabled(false); + changeLink.setText("change"); + } + + private void startEdit() { + accessControlText.setEnabled(true); + changeLink.setText("update"); + } + + @Override + public void linkActivated(HyperlinkEvent e) { + if (accessControlText.isEnabled()) { + // we were already in edit mode. + finishEdit(); + } else { + // Get in to edit mode + startEdit(); + } + } + }); + } + + private void createNASProtocolField(final Volume volume, FormToolkit toolkit, Composite section) { + toolkit.createLabel(section, "NAS Protocols: ", SWT.NONE); + + Composite nasProtocolsComposite = toolkit.createComposite(section); + nasProtocolsComposite.setLayout(new FillLayout()); + + createCheckbox(toolkit, nasProtocolsComposite, "Gluster", true); + final Button nfsCheckBox = createCheckbox(toolkit, nasProtocolsComposite, "NFS", volume.getNASProtocols().contains(NAS_PROTOCOL.NFS)); + + createChangeLinkForNASProtocol(volume, toolkit, section, nfsCheckBox); + } + + private void createChangeLinkForNASProtocol(final Volume volume, FormToolkit toolkit, Composite section, + final Button nfsCheckBox) { + final Hyperlink changeLink = toolkit.createHyperlink(section, "change", SWT.NONE); + changeLink.addHyperlinkListener(new HyperlinkAdapter() { + + private void finishEdit() { + // TODO: Update value to back-end + if (nfsCheckBox.getSelection()) { + volume.enableNFS(); + } else { + volume.disableNFS(); + } + nfsCheckBox.setEnabled(false); + changeLink.setText("change"); + } + + private void startEdit() { + nfsCheckBox.setEnabled(true); + changeLink.setText("update"); + } + + @Override + public void linkActivated(HyperlinkEvent e) { + if (nfsCheckBox.isEnabled()) { + // we were already in edit mode. + finishEdit(); + } else { + // Get in to edit mode + startEdit(); + } + } + }); + } + + private Button createCheckbox(FormToolkit toolkit, Composite parent, String label, boolean selected) { + final Button checkBox = toolkit.createButton(parent, label, SWT.CHECK); + checkBox.setEnabled(false); + checkBox.setSelection(selected); + return checkBox; + } + + private void createVolumePropertiesTab(Volume volume, TabFolder tabFolder, FormToolkit toolkit) { + Composite volumeTab = guiHelper.createTab(tabFolder, volume.getName() + " - Properties", IImageKeys.VOLUME); + final ScrolledForm form = guiHelper.setupForm(volumeTab, toolkit, "Volume Properties [" + volume.getName() + "]"); + createVolumePropertiesSection(volume, toolkit, form); + createVolumeMountingInfoSection(volume, toolkit, form); + createVolumeAlertsSection(volume, toolkit, form); + + volumeTab.layout(); // IMP: lays out the form properly + } + + private void createVolumeLogsTab(Volume volume, TabFolder tabFolder, FormToolkit toolkit) { + Composite volumeTab = guiHelper.createTab(tabFolder, "Logs", IImageKeys.VOLUME); + VolumeLogsPage logsPage = new VolumeLogsPage(volumeTab, SWT.NONE, volume); + + volumeTab.layout(); // IMP: lays out the form properly + } + + private void createVolumeDisksTab(Volume volume, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + Composite volumeDisksTab = guiHelper.createTab(tabFolder, "Disks", IImageKeys.VOLUME); + DisksPage page = new DisksPage(volumeDisksTab, SWT.NONE, site, volume.getDisks()); + + volumeDisksTab.layout(); // IMP: lays out the form properly + } + + private void createVolumeOptionsTab(Volume volume, TabFolder tabFolder, FormToolkit toolkit) { + Composite volumeTab = guiHelper.createTab(tabFolder, "Options", IImageKeys.VOLUME); + VolumeOptionsPage page = new VolumeOptionsPage(volumeTab, SWT.NONE, volume); + + volumeTab.layout(); // IMP: lays out the form properly + } + + @Override + public void createTabs(Entity entity, TabFolder tabFolder, FormToolkit toolkit, IWorkbenchSite site) { + createVolumePropertiesTab((Volume) entity, tabFolder, toolkit); + createVolumeDisksTab((Volume) entity, tabFolder, toolkit, site); + createVolumeOptionsTab((Volume) entity, tabFolder, toolkit); + createVolumeLogsTab((Volume) entity, tabFolder, toolkit); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/ClusterAdapterFactory.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/ClusterAdapterFactory.java new file mode 100644 index 00000000..d7ef44ac --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/ClusterAdapterFactory.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.navigator; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.model.IWorkbenchAdapter; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import com.gluster.storage.management.core.model.Cluster; +import com.gluster.storage.management.core.model.Entity; +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterDataModel; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.Application; +import com.gluster.storage.management.gui.IImageKeys; + +public class ClusterAdapterFactory implements IAdapterFactory { + private IWorkbenchAdapter entityAdapter = new IWorkbenchAdapter() { + + @Override + public Object getParent(Object o) { + return ((Entity) o).getParent(); + } + + @Override + public String getLabel(Object o) { + return ((Entity)o).getName(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public ImageDescriptor getImageDescriptor(Object object) { + String iconPath = null; + + if(object instanceof GlusterDataModel || object instanceof Cluster) { + iconPath = IImageKeys.CLUSTER; + } + + if(object instanceof EntityGroup) { + Class<? extends Entity> entityType = ((EntityGroup) object).getEntityType(); + if(entityType == Volume.class) { + iconPath = IImageKeys.VOLUMES; + } else { + iconPath = IImageKeys.SERVERS; + } + } + + if(object instanceof Volume) { + iconPath = IImageKeys.VOLUME; + } + + if(object instanceof Server || object instanceof GlusterServer) { + iconPath = IImageKeys.SERVER; + } + + return AbstractUIPlugin.imageDescriptorFromPlugin( + Application.PLUGIN_ID, iconPath); + } + + @Override + public Object[] getChildren(Object o) { + return ((Entity)o).getChildren().toArray(); + } + }; + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Object adaptableObject, Class adapterType) { + if (adapterType == IWorkbenchAdapter.class) { + if (adaptableObject instanceof Entity) { + return entityAdapter; + } + } + return null; + } + + @SuppressWarnings("rawtypes") + @Override + public Class[] getAdapterList() { + return new Class[] { IWorkbenchAdapter.class }; + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/NavigationTreeLabelDecorator.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/NavigationTreeLabelDecorator.java new file mode 100644 index 00000000..4cdc2e66 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/navigator/NavigationTreeLabelDecorator.java @@ -0,0 +1,87 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.navigator; + +import org.eclipse.jface.viewers.IDecoration; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ILightweightLabelDecorator; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.GlusterServer; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.Application; +import com.gluster.storage.management.gui.IImageKeys; + +public class NavigationTreeLabelDecorator implements ILightweightLabelDecorator { + + @Override + public void addListener(ILabelProviderListener listener) { + } + + @Override + public void dispose() { + } + + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + @Override + public void removeListener(ILabelProviderListener listener) { + } + + @SuppressWarnings("rawtypes") + @Override + public void decorate(Object element, IDecoration decoration) { + if (element instanceof Volume) { + Volume volume = (Volume) element; + if (volume.getStatus() == Volume.VOLUME_STATUS.OFFLINE) { + decoration.addOverlay(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.OVERLAY_OFFLINE)); + } else { + decoration.addOverlay(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.OVERLAY_ONLINE)); + } + } + + if (element instanceof GlusterServer) { + GlusterServer server = (GlusterServer) element; + if (server.getStatus() == GlusterServer.SERVER_STATUS.OFFLINE) { + decoration.addOverlay(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.OVERLAY_OFFLINE)); + } else { + decoration.addOverlay(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.OVERLAY_ONLINE)); + } + } + + if (element instanceof Server) { + decoration.addOverlay(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.OVERLAY_STAR)); + } + + if(element instanceof EntityGroup && ((EntityGroup)element).getEntityType() == Server.class) { + decoration.addOverlay(AbstractUIPlugin.imageDescriptorFromPlugin(Application.PLUGIN_ID, + IImageKeys.OVERLAY_STAR)); + } + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java new file mode 100644 index 00000000..6be3e78c --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/ServersPage.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.pages; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Server; +import com.gluster.storage.management.gui.EntityGroupContentProvider; +import com.gluster.storage.management.gui.ServerTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class ServersPage extends Composite { + + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private TableViewer tableViewer; + private GUIHelper guiHelper = GUIHelper.getInstance(); + + public enum SERVER_TABLE_COLUMN_INDICES { + NAME, IP_ADDRESSES, NUM_OF_DISKS, TOTAL_DISK_SPACE + }; + + private static final String[] SERVER_TABLE_COLUMN_NAMES = new String[] { "Name", "IP Address(es)", "Number of Disks", "Total Disk Space (GB)" }; + + // public enum SERVER_DISK_TABLE_COLUMN_INDICES { + // NAME, NUM_OF_CPUS, CPU_USAGE, TOTAL_MEMORY, MEMORY_IN_USE, TOTAL_DISK_SPACE, DISK_SPACE_IN_USE + // }; + // + // private static final String[] SERVER_TABLE_COLUMN_NAMES = new String[] { "Name", + // "Number\nof CPUs", "CPU\nUsage (%)", "Total\nMemory (GB)", "Memory\nIn Use (GB)", + // "Total Disk\n Space (GB)", "Disk Space\nin Use (GB)"}; + + public ServersPage(final Composite parent, IWorkbenchSite site, EntityGroup<Server> servers) { + super(parent, SWT.NONE); + + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + setupPageLayout(); + setupPage(site, servers); + parent.layout(); // Important - this actually paints the table + + /** + * Ideally not required. However the table viewer is not getting laid out properly on performing + * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window + */ + addPaintListener(new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + parent.layout(); + } + }); + } + + public void setInput(EntityGroup<Server> servers) { + tableViewer.setInput(servers); + tableViewer.refresh(); + } + + public void addDoubleClickListener(IDoubleClickListener listener) { + tableViewer.addDoubleClickListener(listener); + } + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(1, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + } + + private void setupServerTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(false); + + TableColumnLayout tableColumnLayout = guiHelper.createTableColumnLayout(table, SERVER_TABLE_COLUMN_NAMES); + parent.setLayout(tableColumnLayout); + + setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.NAME, SWT.CENTER, 70); + setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.IP_ADDRESSES, SWT.CENTER, 100); + setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.NUM_OF_DISKS, SWT.CENTER, 70); + setColumnProperties(table, SERVER_TABLE_COLUMN_INDICES.TOTAL_DISK_SPACE, SWT.CENTER, 70); + // setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.NUM_OF_CPUS, SWT.CENTER, 90); + // setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.CPU_USAGE, SWT.CENTER, 90); + // setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.TOTAL_MEMORY, SWT.CENTER, 90); + // setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.MEMORY_IN_USE, SWT.CENTER, 90); + // setColumnProperties(table, SERVER_DISK_TABLE_COLUMN_INDICES.DISK_SPACE_IN_USE, SWT.CENTER, 90); + } + + private TableViewer createServerTableViewer(Composite parent) { + TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + // TableViewer tableViewer = new TableViewer(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new ServerTableLabelProvider()); + tableViewer.setContentProvider(new EntityGroupContentProvider<Server>()); + + setupServerTable(parent, tableViewer.getTable()); + + return tableViewer; + } + + private Composite createTableViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NONE); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return tableViewerComposite; + } + + private void setupPage(IWorkbenchSite site, EntityGroup<Server> servers) { + Text filterText = guiHelper.createFilterText(toolkit, this); + + Composite tableViewerComposite = createTableViewerComposite(); + tableViewer = createServerTableViewer(tableViewerComposite); + site.setSelectionProvider(tableViewer); + + // Create a case insensitive filter for the table viewer using the filter text field + guiHelper.createFilter(tableViewer, filterText, false); + + tableViewer.setInput(servers); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + private void setColumnProperties(Table table, SERVER_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } +} diff --git a/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java new file mode 100644 index 00000000..9e25a018 --- /dev/null +++ b/src/com.gluster.storage.management.gui/src/com/gluster/storage/management/gui/views/pages/VolumesPage.java @@ -0,0 +1,163 @@ +/******************************************************************************* + * Copyright (c) 2011 Gluster, Inc. <http://www.gluster.com> + * This file is part of Gluster Management Console. + * + * Gluster Management Console is free software; you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Gluster Management Console is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License + * for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + *******************************************************************************/ +package com.gluster.storage.management.gui.views.pages; + +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.PaintEvent; +import org.eclipse.swt.events.PaintListener; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IWorkbenchSite; +import org.eclipse.ui.forms.widgets.FormToolkit; + +import com.gluster.storage.management.core.model.EntityGroup; +import com.gluster.storage.management.core.model.Volume; +import com.gluster.storage.management.gui.EntityGroupContentProvider; +import com.gluster.storage.management.gui.VolumeTableLabelProvider; +import com.gluster.storage.management.gui.utils.GUIHelper; + +public class VolumesPage extends Composite { + + private final FormToolkit toolkit = new FormToolkit(Display.getCurrent()); + private TableViewer tableViewer; + private GUIHelper guiHelper = GUIHelper.getInstance(); + + public enum VOLUME_TABLE_COLUMN_INDICES { + NAME, VOLUME_TYPE, NUM_OF_DISKS, TRANSPORT_TYPE, VOLUME_STATUS + }; + + private static final String[] VOLUME_TABLE_COLUMN_NAMES = new String[] { "Name", + "Volume Type", "Number of\nDisks", "Transport Type", "Status" }; + + public VolumesPage(final Composite parent, IWorkbenchSite site, EntityGroup<Volume> volumes) { + super(parent, SWT.NONE); + + addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + toolkit.dispose(); + } + }); + + toolkit.adapt(this); + toolkit.paintBordersFor(this); + + setupPageLayout(); + setupVolumeTableViewer(site, volumes); + + parent.layout(); // Important - this actually paints the table + + /** + * Ideally not required. However the table viewer is not getting laid out properly on performing + * "maximize + restore" So this is a hack to make sure that the table is laid out again on re-size of the window + */ + addPaintListener(new PaintListener() { + + @Override + public void paintControl(PaintEvent e) { + parent.layout(); + } + }); + } + + public void addDoubleClickListener(IDoubleClickListener listener) { + tableViewer.addDoubleClickListener(listener); + } + + private void setupPageLayout() { + final GridLayout layout = new GridLayout(1, false); + layout.verticalSpacing = 10; + layout.marginTop = 10; + setLayout(layout); + } + + private void setupVolumeTable(Composite parent, Table table) { + table.setHeaderVisible(true); + table.setLinesVisible(true); + + TableColumnLayout columnLayout = guiHelper.createTableColumnLayout(table, VOLUME_TABLE_COLUMN_NAMES); + parent.setLayout(columnLayout); + + setColumnProperties(table, VOLUME_TABLE_COLUMN_INDICES.VOLUME_STATUS, SWT.CENTER, 50); + setColumnProperties(table, VOLUME_TABLE_COLUMN_INDICES.NUM_OF_DISKS, SWT.CENTER, 50); + setColumnProperties(table, VOLUME_TABLE_COLUMN_INDICES.TRANSPORT_TYPE, SWT.CENTER, 70); + } + + private TableViewer createVolumeTableViewer(Composite parent) { + TableViewer tableViewer = CheckboxTableViewer.newCheckList(parent, SWT.FLAT | SWT.FULL_SELECTION | SWT.MULTI); + tableViewer.setLabelProvider(new VolumeTableLabelProvider()); + tableViewer.setContentProvider(new EntityGroupContentProvider<Volume>()); + + setupVolumeTable(parent, tableViewer.getTable()); + + return tableViewer; + } + + private Composite createTableViewerComposite() { + Composite tableViewerComposite = new Composite(this, SWT.NO); + tableViewerComposite.setLayout(new FillLayout(SWT.HORIZONTAL)); + tableViewerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + return tableViewerComposite; + } + + private void setupVolumeTableViewer(IWorkbenchSite site, EntityGroup<Volume> volumes) { + Text filterText = guiHelper.createFilterText(toolkit, this); + + Composite tableViewerComposite = createTableViewerComposite(); + tableViewer = createVolumeTableViewer(tableViewerComposite); + site.setSelectionProvider(tableViewer); + + // Create a case insensitive filter for the table viewer using the filter text field + guiHelper.createFilter(tableViewer, filterText, false); + tableViewer.setInput(volumes); + } + + /** + * Sets properties for alignment and weight of given column of given table + * + * @param table + * @param columnIndex + * @param alignment + * @param weight + */ + public void setColumnProperties(Table table, VOLUME_TABLE_COLUMN_INDICES columnIndex, int alignment, int weight) { + TableColumn column = table.getColumn(columnIndex.ordinal()); + column.setAlignment(alignment); + + TableColumnLayout tableColumnLayout = (TableColumnLayout) table.getParent().getLayout(); + tableColumnLayout.setColumnData(column, new ColumnWeightData(weight)); + } + + public void setInput(EntityGroup<Volume> volumes) { + tableViewer.setInput(volumes); + tableViewer.refresh(); + } +} |
