diff --git a/cave/build/cave/memorySettings.xml b/cave/build/cave/memorySettings.xml index 711e74b738..82f16244c1 100644 --- a/cave/build/cave/memorySettings.xml +++ b/cave/build/cave/memorySettings.xml @@ -90,6 +90,23 @@ + + + + -component + gfeclient + + + + + 1536M + + + + DEFAULT + + + @@ -148,6 +165,23 @@ + + + + -component + gfeclient + + + + + 2048M + + + + DEFAULT + + + - \ No newline at end of file + diff --git a/cave/build/p2-build.xml b/cave/build/p2-build.xml index ffa3684862..eafc720c43 100644 --- a/cave/build/p2-build.xml +++ b/cave/build/p2-build.xml @@ -276,6 +276,14 @@ + + + + + + @@ -407,6 +415,20 @@ + + + + + + + + + + - - + + diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseAlaska.xml b/cave/build/static/common/cave/etc/menus/upperair/baseAlaska.xml index 133d24de77..daa46844e2 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseAlaska.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseAlaska.xml @@ -21,83 +21,83 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseAtlantic.xml b/cave/build/static/common/cave/etc/menus/upperair/baseAtlantic.xml index fe68b70a83..92d6c70827 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseAtlantic.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseAtlantic.xml @@ -21,105 +21,105 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseAustralia.xml b/cave/build/static/common/cave/etc/menus/upperair/baseAustralia.xml index 0f9e751592..410b2f3aee 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseAustralia.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseAustralia.xml @@ -21,147 +21,147 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaCentral.xml b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaCentral.xml index 8afaa1e04e..53e09ad1a8 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaCentral.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaCentral.xml @@ -21,22 +21,22 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaEastern.xml b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaEastern.xml index 973ef9ef17..b032982927 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaEastern.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaEastern.xml @@ -21,87 +21,87 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaNorth.xml b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaNorth.xml index f90fceb603..6c3d0eccba 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaNorth.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaNorth.xml @@ -21,67 +21,67 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaWestern.xml b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaWestern.xml index 4634aa2074..5581b7f546 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseCanadaWestern.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseCanadaWestern.xml @@ -21,52 +21,52 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseChina.xml b/cave/build/static/common/cave/etc/menus/upperair/baseChina.xml index c473b72131..c82fd472c2 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseChina.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseChina.xml @@ -21,92 +21,92 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseJapan.xml b/cave/build/static/common/cave/etc/menus/upperair/baseJapan.xml index 99eae4555f..5059c2c680 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseJapan.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseJapan.xml @@ -21,161 +21,161 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseMexico.xml b/cave/build/static/common/cave/etc/menus/upperair/baseMexico.xml index 03da31f119..6a73a1b55b 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseMexico.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseMexico.xml @@ -21,138 +21,138 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/basePacificEast.xml b/cave/build/static/common/cave/etc/menus/upperair/basePacificEast.xml index 388737da1c..17199f5aa2 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/basePacificEast.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/basePacificEast.xml @@ -21,68 +21,68 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/basePacificWest.xml b/cave/build/static/common/cave/etc/menus/upperair/basePacificWest.xml index 94968383ab..31857a57ca 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/basePacificWest.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/basePacificWest.xml @@ -21,120 +21,120 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseRussia.xml b/cave/build/static/common/cave/etc/menus/upperair/baseRussia.xml index 953dd9f508..c74031c639 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseRussia.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseRussia.xml @@ -21,147 +21,147 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseUSCentral.xml b/cave/build/static/common/cave/etc/menus/upperair/baseUSCentral.xml index 874aa0a89d..f54605d3b6 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseUSCentral.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseUSCentral.xml @@ -21,117 +21,117 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseUSEastern.xml b/cave/build/static/common/cave/etc/menus/upperair/baseUSEastern.xml index cf8cccd01d..03af88a18d 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseUSEastern.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseUSEastern.xml @@ -21,162 +21,162 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/build/static/common/cave/etc/menus/upperair/baseUSWestern.xml b/cave/build/static/common/cave/etc/menus/upperair/baseUSWestern.xml index 0c35e883db..0b8403fd01 100644 --- a/cave/build/static/common/cave/etc/menus/upperair/baseUSWestern.xml +++ b/cave/build/static/common/cave/etc/menus/upperair/baseUSWestern.xml @@ -21,162 +21,162 @@ + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> + editorType="gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor"> \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.classpath b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.project b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.project new file mode 100644 index 0000000000..a964c41ac0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.comm.xmpp + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..cee65c0334 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Jul 20 17:19:32 CDT 2012 +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/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..0486cc904b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/META-INF/MANIFEST.MF @@ -0,0 +1,17 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Xmpp +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.comm.xmpp;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.comm.xmpp.Activator +Bundle-Vendor: RAYTHEON +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.ecf;bundle-version="3.1.300", + org.eclipse.ecf.provider.xmpp;bundle-version="3.2.0", + org.eclipse.ecf.provider;bundle-version="4.2.100", + org.eclipse.ecf.presence;bundle-version="2.0.0", + org.eclipse.ecf.sharedobject;bundle-version="2.2.100", + org.jivesoftware.smack;bundle-version="3.1.100" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.collaboration.comm.xmpp diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/build.properties b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/plugin.xml b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/plugin.xml new file mode 100644 index 0000000000..e99b5082c5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/plugin.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/Activator.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/Activator.java new file mode 100644 index 0000000000..7feee87aad --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/Activator.java @@ -0,0 +1,30 @@ +package com.raytheon.uf.viz.collaboration.comm.xmpp; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/XMPPContainer.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/XMPPContainer.java new file mode 100644 index 0000000000..e76063905b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/XMPPContainer.java @@ -0,0 +1,356 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp; + +import java.io.IOException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.events.ContainerConnectedEvent; +import org.eclipse.ecf.core.events.ContainerConnectingEvent; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.security.IConnectContext; +import org.eclipse.ecf.core.sharedobject.SharedObjectAddException; +import org.eclipse.ecf.core.user.User; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.internal.provider.xmpp.Messages; +import org.eclipse.ecf.internal.provider.xmpp.XmppPlugin; +import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnectionObjectPacketEvent; +import org.eclipse.ecf.presence.chatroom.IChatRoomContainer; +import org.eclipse.ecf.presence.chatroom.IChatRoomManager; +import org.eclipse.ecf.presence.im.IChatManager; +import org.eclipse.ecf.presence.roster.IRosterManager; +import org.eclipse.ecf.provider.comm.AsynchEvent; +import org.eclipse.ecf.provider.comm.ConnectionCreateException; +import org.eclipse.ecf.provider.comm.ISynchAsynchConnection; +import org.eclipse.ecf.provider.generic.ContainerMessage; +import org.eclipse.osgi.util.NLS; +import org.jivesoftware.smack.XMPPException; + +import com.raytheon.uf.viz.collaboration.comm.xmpp.internal.XMPPChatRoomContainer; +import com.raytheon.uf.viz.collaboration.comm.xmpp.internal.XMPPChatRoomManager; +import com.raytheon.uf.viz.collaboration.comm.xmpp.internal.XMPPContainerPresenceHelper; +import com.raytheon.uf.viz.collaboration.comm.xmpp.internal.smack.ECFConnection; + +/** + * Extends the ECF XMPPContainer but overrides any methods which use the + * chatRoomManager or containerPresenceHelper to use viz specific instances. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 20, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@SuppressWarnings("restriction") +public class XMPPContainer extends org.eclipse.ecf.provider.xmpp.XMPPContainer { + + /** + * custom chat room manager. + */ + XMPPChatRoomManager chatRoomManager = null; + + XMPPContainerPresenceHelper presenceHelper = null; + + public XMPPContainer() throws Exception { + this(DEFAULT_KEEPALIVE); + } + + public XMPPContainer(int ka) throws Exception { + super(ka); + chatRoomManager = new XMPPChatRoomManager(getID()); + presenceHelper = new XMPPContainerPresenceHelper(this); + } + + public XMPPContainer(String userhost, int ka) throws Exception { + super(userhost, ka); + chatRoomManager = new XMPPChatRoomManager(getID()); + presenceHelper = new XMPPContainerPresenceHelper(this); + } + + /** + * Overridden to return custom chatRoomManager + */ + @Override + public IChatRoomManager getChatRoomManager() { + return chatRoomManager; + } + + /** + * Overridden to use rosterManager from custom presenceHelper + */ + @Override + public IRosterManager getRosterManager() { + return presenceHelper.getRosterManager(); + } + + /** + * Overridden to use chatManager from custom presenceHelper + */ + @Override + public IChatManager getChatManager() { + return presenceHelper.getChatManager(); + } + + /** + * Overridden to disconnect custom presenceHelper and connect our own + * instead. Also takes the functionality from the connect method in + * ClientSOContainer so that we can complete all the necessary functionality + * of the super's super method in our own method. The super method + * originally called super with a different presence helper id and that + * would break part of our functionality + */ + @Override + public void connect(ID remote, IConnectContext joinContext) + throws ContainerConnectException { + try { + getSharedObjectManager().addSharedObject(presenceHelperID, + presenceHelper, null); + + // following taken from + // ClientSOContainer.connect(ID,IConnectContext); + try { + if (isClosing) + throw new IllegalStateException("Container closing"); //$NON-NLS-1$ + if (remote == null) + throw new ContainerConnectException( + "targetID cannot be null"); //$NON-NLS-1$ + Object response = null; + synchronized (getConnectLock()) { + // Throw if already connected + if (isConnected()) + throw new IllegalStateException( + "Container already connected connectedID=" + getConnectedID()); //$NON-NLS-1$ + // Throw if connecting + if (isConnecting()) + throw new IllegalStateException("Container connecting"); //$NON-NLS-1$ + // else we're entering connecting state + // first notify synchonously + final ISynchAsynchConnection aConnection = createConnection( + remote, joinContext); + setStateConnecting(aConnection); + + fireContainerEvent(new ContainerConnectingEvent( + this.getID(), remote, joinContext)); + + final Object connectData = getConnectData(remote, + joinContext); + final int connectTimeout = getConnectTimeout(); + + synchronized (aConnection) { + + try { + // Make connect call + response = aConnection.connect(remote, connectData, + connectTimeout); + } catch (final ECFException e) { + if (getConnection() != aConnection) + disconnect(aConnection); + else + setStateDisconnected(aConnection); + throw e; + } + // If not in correct state, disconnect and return + if (getConnection() != aConnection) { + disconnect(aConnection); + throw new IllegalStateException( + "Container connect failed because not in correct state"); //$NON-NLS-1$ + } + ID serverID = null; + try { + serverID = handleConnectResponse(remote, response); + } catch (final Exception e) { + setStateDisconnected(aConnection); + throw e; + } + setStateConnected(serverID, aConnection); + // notify listeners + fireContainerEvent(new ContainerConnectedEvent( + this.getID(), remoteServerID)); + aConnection.start(); + } + } + } catch (XMPPException e) { + throw new ContainerConnectException(e.getMessage(), e); + } catch (final ECFException e) { + final IStatus s = e.getStatus(); + throw new ContainerConnectException(s.getMessage(), + s.getException()); + } catch (final Exception e) { + throw new ContainerConnectException(e.getLocalizedMessage(), e); + } + + XmppPlugin.getDefault().registerService(this); + } catch (final ContainerConnectException e) { + disconnect(); + throw e; + } catch (final SharedObjectAddException e1) { + disconnect(); + throw new ContainerConnectException(NLS.bind( + Messages.XMPPContainer_EXCEPTION_ADDING_SHARED_OBJECT, + presenceHelperID), e1); + } + // end ClientSOContainer code + + getSharedObjectManager().removeSharedObject(presenceHelperID); + try { + getSharedObjectManager().addSharedObject(presenceHelperID, + presenceHelper, null); + } catch (SharedObjectAddException e) { + disconnect(); + throw new ContainerConnectException(NLS.bind( + Messages.XMPPContainer_EXCEPTION_ADDING_SHARED_OBJECT, + presenceHelperID), e); + } + } + + /** + * Need to override this method from ClientSOContainer so that our connect + * method can set the connection and the connectionState and the + * remoteServerID + * + * Taken from ECF. + * + * @param serverID + * @param conn + */ + private void setStateConnected(ID serverID, ISynchAsynchConnection conn) { + connectionState = CONNECTED; + connection = conn; + remoteServerID = serverID; + } + + /** + * Need to override this method out of ClientSOContainer so that our connect + * method can set the connectionState and disconnect the connection + * + * Taken from ECF + * + */ + private void setStateDisconnected(ISynchAsynchConnection conn) { + disconnect(conn); + connectionState = DISCONNECTED; + connection = null; + remoteServerID = null; + } + + /** + * Need to override this method out of ClientSOContainer so that our connect + * method can set the connectionState and the connection + * + * Taken from ECF + * + * @param conn + */ + private void setStateConnecting(ISynchAsynchConnection conn) { + connectionState = CONNECTING; + connection = conn; + } + + /** + * Overridden to disconnect custom chatRoomManager and custom presenceHelper + */ + @Override + public void disconnect() { + super.disconnect(); + chatRoomManager.setConnection(null, null, null); + presenceHelper.disconnect(); + } + + /** + * Overridden to return custom chatRoomManager + */ + @Override + public void dispose() { + super.dispose(); + chatRoomManager.dispose(); + } + + /** + * Overriden to set connection in custom chatRoomManager and to set user in + * custom presenceHelper + */ + @Override + protected ID handleConnectResponse(ID originalTarget, Object serverData) + throws Exception { + ID result = super.handleConnectResponse(originalTarget, serverData); + chatRoomManager.setConnection(getConnectNamespace(), originalTarget, + getECFConnection()); + presenceHelper.setUser(new User(originalTarget)); + return result; + } + + /** + * Overriden to cast ECFConnection to viz implementation + */ + public ECFConnection getECFConnection() { + return (ECFConnection) super.getConnection(); + } + + /** + * Overriden to create viz ECFConnection + */ + @Override + protected ISynchAsynchConnection createConnection(ID remoteSpace, + Object data) throws ConnectionCreateException { + final boolean google = isGoogle(remoteSpace); + return new ECFConnection(google, getConnectNamespace(), receiver); + } + + /** + * Adapted from super.processAsynch to use custom chatRoomManager for chat + * events. + */ + @Override + protected void processAsynch(AsynchEvent e) { + try { + if (e instanceof ECFConnectionObjectPacketEvent) { + // It's an ECF object message + final ECFConnectionObjectPacketEvent evt = (ECFConnectionObjectPacketEvent) e; + final Object obj = evt.getObjectValue(); + // this should be a ContainerMessage + final Object cm = deserializeContainerMessage((byte[]) obj); + if (cm == null) + super.processAsynch(e); + final ContainerMessage contMessage = (ContainerMessage) cm; + final IChatRoomContainer chat = chatRoomManager + .findReceiverChatRoom(contMessage.getToContainerID()); + if (chat != null && chat instanceof XMPPChatRoomContainer) { + final XMPPChatRoomContainer cont = (XMPPChatRoomContainer) chat; + cont.handleContainerMessage(contMessage); + return; + } + super.processAsynch(e); + } + } catch (final IOException except) { + log(NLS.bind(Messages.XMPPContainer_EXCEPTION_HANDLING_ASYCH_EVENT, + e), except); + } + super.processAsynch(e); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomContainer.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomContainer.java new file mode 100644 index 0000000000..2c89a04abd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomContainer.java @@ -0,0 +1,235 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp.internal; + +import java.io.IOException; +import java.util.HashMap; + +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.core.security.IConnectContext; +import org.eclipse.ecf.core.sharedobject.SharedObjectAddException; +import org.eclipse.ecf.internal.provider.xmpp.events.ChatMembershipEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.IQEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.MessageEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.PresenceEvent; +import org.eclipse.ecf.presence.IIMMessageListener; +import org.eclipse.ecf.presence.chatroom.IChatRoomParticipantListener; +import org.eclipse.ecf.provider.generic.SOWrapper; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Presence; + +import com.raytheon.uf.viz.collaboration.comm.xmpp.XMPPContainer; +import com.raytheon.uf.viz.collaboration.comm.xmpp.internal.smack.ECFConnection; + +/** + * Override the ECF XMPPChatRoomContainer but provide a custom viz + * XMPPChatRoomContainerHelper + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 20, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +@SuppressWarnings("restriction") +public class XMPPChatRoomContainer extends + org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomContainer { + + private static final String CONTAINER_HELPER_ID = XMPPContainer.class + .getName() + ".xmppgroupchathandler"; //$NON-NLS-1$ + + private ID containerHelperID; + + /** + * Use viz version of chatRoomContainerHelper. + */ + private XMPPChatRoomContainerHelper containerHelper; + + public XMPPChatRoomContainer(ECFConnection conn, Namespace usernamespace) + throws IDCreateException { + super(conn, usernamespace); + this.containerHelperID = IDFactory.getDefault().createStringID( + CONTAINER_HELPER_ID); + this.containerHelper = new XMPPChatRoomContainerHelper(usernamespace, + getXMPPConnection()); + } + + /** + * Overridden to use custom containerHelper. + */ + @Override + public void addChatRoomParticipantListener( + IChatRoomParticipantListener participantListener) { + if (containerHelper != null) { + containerHelper.addChatParticipantListener(participantListener); + } + } + + /** + * Overridden to use custom containerHelper. + */ + @Override + public void addMessageListener(IIMMessageListener listener) { + containerHelper.addChatRoomMessageListener(listener); + } + + /** + * Overridden to use custom containerHelper. + */ + @Override + protected void addSharedObjectToContainer(ID remote) + throws SharedObjectAddException { + getSharedObjectManager().addSharedObject(containerHelperID, + containerHelper, new HashMap()); + } + + /** + * Overridden to clean up custom containerHelper. + */ + @Override + protected void cleanUpConnectFail() { + super.cleanUpConnectFail(); + if (containerHelper != null) { + getSharedObjectManager().removeSharedObject(containerHelperID); + containerHelper = null; + containerHelperID = null; + } + } + + /** + * Overridden to connect custom containerHelper. + */ + @Override + public void connect(ID remote, IConnectContext connectContext) + throws ContainerConnectException { + super.connect(remote, connectContext); + containerHelper.setRoomID(remoteServerID); + } + + /** + * Overridden to disconnect custom containerHelper. + */ + @Override + public void disconnect() { + super.disconnect(); + if (containerHelper != null) + containerHelper.disconnect(); + } + + /** + * Overridden to dispose custom containerHelper. + */ + @Override + public void dispose() { + if (containerHelperID != null) { + getSharedObjectManager().removeSharedObject(containerHelperID); + containerHelperID = null; + } + super.dispose(); + if (containerHelper != null) + containerHelper.dispose(getID()); + containerHelper = null; + } + + /** + * Overridden to use custom containerHelper. + */ + @Override + public ID[] getChatRoomParticipants() { + return containerHelper.getChatRoomParticipants(); + } + + /** + * Overridden to use custom containerHelper. + */ + @Override + public void removeChatRoomParticipantListener( + IChatRoomParticipantListener participantListener) { + if (containerHelper != null) { + containerHelper.removeChatParticipantListener(participantListener); + } + } + + /** + * Overridden to use custom containerHelper. + */ + @Override + public void removeMessageListener(IIMMessageListener listener) { + containerHelper.removeChatRoomMessageListener(listener); + } + + /** + * Overridden to use custom containerHelperID. + */ + @Override + protected void handleChatMessage(Message mess) throws IOException { + final SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new MessageEvent(mess)); + } + } + + /** + * Overridden to use custom containerHelperID. + */ + @Override + protected void handleIQMessage(IQ mess) throws IOException { + final SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new IQEvent(mess)); + } + } + + /** + * Overridden to use custom containerHelperID. + */ + @Override + protected void handlePresenceMessage(Presence mess) throws IOException { + final SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new PresenceEvent(mess)); + } + } + + /** + * Overridden to use custom containerHelperID. + */ + @Override + protected void handleChatMembershipEvent(String from, boolean add) { + final SOWrapper wrap = getSharedObjectWrapper(containerHelperID); + if (wrap != null) { + wrap.deliverEvent(new ChatMembershipEvent(from, add)); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomContainerHelper.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomContainerHelper.java new file mode 100644 index 0000000000..6459b2c484 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomContainerHelper.java @@ -0,0 +1,178 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.provider.xmpp.events.ChatMembershipEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.PresenceEvent; +import org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnection; +import org.eclipse.ecf.presence.IIMMessageListener; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.chatroom.IChatRoomParticipantListener; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.Presence; + +/** + * Extend the ECF XMPPChatRoomContainerHelper with three changes (1) add + * properties to presence events in a room. (2) expose methods needed by the Viz + * version of XMPPChatRoomContainer. (3) disable the default chatMembership + * events and instead fire ChatMembershipEvents when the presence changes. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 20, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@SuppressWarnings("restriction") +public class XMPPChatRoomContainerHelper extends + org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomContainerHelper { + + /** + * Need our own list to track who is in the room. + */ + private final List chatRoomContainerParticipants = Collections + .synchronizedList(new ArrayList()); + + public XMPPChatRoomContainerHelper(Namespace usernamespace, + XMPPConnection conn) { + super(usernamespace, conn); + } + + /** + * exposed method to this package. + */ + @Override + protected void setRoomID(ID roomID) { + super.setRoomID(roomID); + } + + /** + * exposed method to this package. + */ + @Override + protected void disconnect() { + super.disconnect(); + } + + /** + * exposed method to this package. + */ + @Override + protected void addChatParticipantListener( + IChatRoomParticipantListener listener) { + super.addChatParticipantListener(listener); + } + + /** + * exposed method to this package. + */ + @Override + protected void removeChatParticipantListener( + IChatRoomParticipantListener listener) { + super.removeChatParticipantListener(listener); + } + + /** + * exposed method to this package. + */ + @Override + protected void addChatRoomMessageListener(IIMMessageListener msgListener) { + super.addChatRoomMessageListener(msgListener); + } + + /** + * exposed method to this package. + */ + @Override + protected ID createUserIDFromName(String name) { + return super.createUserIDFromName(name); + } + + /** + * adapted from super.createIPresence, but modified to add properties from + * the packet. + */ + @Override + protected IPresence createIPresence(Presence xmppPresence) { + final String status = xmppPresence.getStatus(); + final IPresence newPresence = new org.eclipse.ecf.presence.Presence( + createIPresenceType(xmppPresence), status, + createIPresenceMode(xmppPresence), + ECFConnection.getPropertiesFromPacket(xmppPresence)); + return newPresence; + } + + /** + * Overridden to also fire ChatMembershipEvent, see + * handleChatMembershipEvent for more information on why this is done. + */ + @Override + protected void handlePresenceEvent(PresenceEvent evt) { + super.handlePresenceEvent(evt); + final Presence xmppPresence = evt.getPresence(); + final String from = canonicalizeRoomFrom(xmppPresence.getFrom()); + final ID fromID = createUserIDFromName(from); + if (xmppPresence.getType().equals(Presence.Type.available)) { + if (!chatRoomContainerParticipants.contains(fromID)) { + chatRoomContainerParticipants.add(fromID); + super.handleChatMembershipEvent(new ChatMembershipEvent( + xmppPresence.getFrom(), true)); + } + } else { + chatRoomContainerParticipants.remove(fromID); + super.handleChatMembershipEvent(new ChatMembershipEvent( + xmppPresence.getFrom(), false)); + } + } + + /** + * The ECF version of this class will not always correctly fire these events + * for the user that created this room. The reason is because + * XMPPChatRoomManager.createChatRoom creates a temporary MultiUserChat to + * create the room but this MultiUserChat registers with the + * RoomListenerMultiplexor and it does not deregister until finalize. When + * we connect to the room it will create a second MultiUserChat and it is + * possible they are both registered. When the temporary chat is garbage + * collected it removes the room from the RoomListenerMultiplexor and events + * for that room are ignored. Most events do not come from the + * RoomListenerMultiplexor so there is no problems but the + * ChatMembershipEvent comes from that and breaks sometimes so we disable it + * and instead fire these events from handlePresenceEvent since that event + * is fired separately from the RoomListenerMultiplexor. + */ + @Override + protected void handleChatMembershipEvent(ChatMembershipEvent evt) { + ; // disabled + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomManager.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomManager.java new file mode 100644 index 0000000000..6d5936366c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPChatRoomManager.java @@ -0,0 +1,276 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp.internal; + +import java.util.Map; + +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.internal.provider.xmpp.Messages; +import org.eclipse.ecf.presence.chatroom.ChatRoomCreateException; +import org.eclipse.ecf.presence.chatroom.IChatRoomContainer; +import org.eclipse.ecf.presence.chatroom.IChatRoomInfo; +import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smackx.Form; +import org.jivesoftware.smackx.muc.MultiUserChat; +import org.jivesoftware.smackx.muc.RoomInfo; + +import com.raytheon.uf.viz.collaboration.comm.xmpp.internal.smack.ECFConnection; + +/** + * Extend the ECF XMPPChatRoomManager but add the ability to use a custom viz + * chat room container. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 20, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +@SuppressWarnings("restriction") +public class XMPPChatRoomManager extends + org.eclipse.ecf.internal.provider.xmpp.XMPPChatRoomManager { + + private static final String PROP_XMPP_SUBJECT = "subject"; + + /** + * Super has ecfConnection but it is private and we need it. + */ + private ECFConnection ecfConnection = null; + + /** + * Super has connectNamespace but it is private and we need it. + */ + private Namespace connectNamespace = null; + + public XMPPChatRoomManager(ID containerID) { + super(containerID); + } + + /** + * Overriden to so we can grab the ecfConnection and namespace + */ + public void setConnection(Namespace connectNamespace, ID connectedID, + ECFConnection connection) { + super.setConnection(connectNamespace, connectedID, connection); + this.connectNamespace = connectNamespace; + this.ecfConnection = connection; + } + + /** + * Overriden to wrap the roomInfo in a custom roomInfo. + */ + @Override + protected IChatRoomInfo getChatRoomInfo(ID roomID) { + IChatRoomInfo result = super.getChatRoomInfo(roomID); + if (result != null) { + result = new ECFRoomInfo(result); + } + return result; + } + + /** + * Overriden to wrap the roomInfo in a custom roomInfo. + */ + @Override + public IChatRoomInfo getChatRoomInfo(String roomname) { + IChatRoomInfo result = super.getChatRoomInfo(roomname); + if (result != null) { + result = new ECFRoomInfo(result); + } else if (ecfConnection != null) { + // If the result is null then it is possible that ecf silently + // disgarded an exception from xmpp, we would like some way to be + // able to capture that exception so this code will + // attempt to find the room itself and log errors. + Exception exception = null; + String mucName = null; + try { + XMPPConnection conn = ecfConnection.getXMPPConnection(); + XMPPRoomID roomID = new XMPPRoomID(connectNamespace, conn, + roomname); + mucName = roomID.getMucString(); + RoomInfo info = MultiUserChat.getRoomInfo(conn, mucName); + if (info != null) { + // Theoretically this will never hit but if it does there is + // no way of getting a super.ECFRoomInfo even + // though we know the room exists, so just log it. + System.err + .println("XMPPChatRoomManager cannot find info for room " + + roomname + " but it exists."); + } + } catch (XMPPException e) { + if (e.getXMPPError().getCode() != 404) { + // 404 is considered normal, everything else is bad + exception = e; + } + } catch (final Exception e) { + exception = e; + } + if (exception != null) { + System.err + .println("XMPPChatRoomManager cannot find info for room " + + roomname + + " when looking for " + + String.valueOf(mucName)); + exception.printStackTrace(); + } + } + return result; + } + + /** + * Overriden to use the same nickname that is used when joining. + */ + @Override + public IChatRoomInfo createChatRoom(String roomname, Map properties) + throws ChatRoomCreateException { + if (roomname == null) + throw new ChatRoomCreateException(roomname, + Messages.XMPPChatRoomManager_EXCEPTION_ROOM_CANNOT_BE_NULL); + try { + String nickname = ecfConnection.getXMPPConnection().getUser(); + final String server = ecfConnection.getXMPPConnection().getHost(); + final String domain = (properties == null) ? XMPPRoomID.DOMAIN_DEFAULT + : (String) properties.get(PROP_XMPP_CONFERENCE); + final String conference = XMPPRoomID.fixConferenceDomain(domain, + server); + final String roomID = roomname + XMPPRoomID.AT_SIGN + conference; + // create proxy to the room + final MultiUserChat muc = new MultiUserChat( + ecfConnection.getXMPPConnection(), roomID); + + if (!checkRoom(conference, roomID)) { + // otherwise create a new one + + /** + * This is the reason we override super.createChatRoom, when we + * join it only uses the username, not then host so we must do + * the same here or a user departed event is triggered for + * user@host when user arrives. + */ + if (nickname.contains("@")) { + nickname = nickname.split("@")[0]; + } + muc.create(nickname); + muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT)); + final String subject = (properties == null) ? null + : (String) properties.get(PROP_XMPP_SUBJECT); + if (subject != null) + muc.changeSubject(subject); + } + + } catch (final XMPPException e) { + throw new ChatRoomCreateException(roomname, e.getMessage(), e); + } + return getChatRoomInfo(roomname); + } + + /** + * Custom roomInfo that wraps another roomInfo and overrides + * createChatRoomContainer to return viz container. + */ + class ECFRoomInfo implements IChatRoomInfo { + + IChatRoomInfo realInfo; + + public ECFRoomInfo(IChatRoomInfo realInfo) { + this.realInfo = realInfo; + } + + public String getDescription() { + return realInfo.getDescription(); + } + + public String getSubject() { + return realInfo.getSubject(); + } + + public ID getRoomID() { + return realInfo.getRoomID(); + } + + public int getParticipantsCount() { + return realInfo.getParticipantsCount(); + } + + public String getName() { + return realInfo.getName(); + } + + public boolean isPersistent() { + return realInfo.isPersistent(); + } + + public boolean requiresPassword() { + return realInfo.requiresPassword(); + } + + public boolean isModerated() { + return realInfo.isModerated(); + } + + public ID getConnectedID() { + return realInfo.getConnectedID(); + } + + public Object getAdapter(Class adapter) { + return realInfo.getAdapter(adapter); + } + + /** + * Adapted from the ECF version of ECFRoomInfo but changed to return our + * custom container. + */ + public IChatRoomContainer createChatRoomContainer() + throws ContainerCreateException { + XMPPChatRoomContainer chatContainer = null; + if (ecfConnection == null) + throw new ContainerCreateException( + Messages.XMPPChatRoomManager_EXCEPTION_CONTAINER_DISCONNECTED); + try { + chatContainer = new XMPPChatRoomContainer(ecfConnection, + connectNamespace); + addChat(chatContainer); + return chatContainer; + } catch (final IDCreateException e) { + throw new ContainerCreateException( + Messages.XMPPChatRoomManager_EXCEPTION_CREATING_CHAT_CONTAINER, + e); + } + } + + public String toString() { + return realInfo.toString(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPContainerInstantiator.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPContainerInstantiator.java new file mode 100644 index 0000000000..c232394ca8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPContainerInstantiator.java @@ -0,0 +1,85 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp.internal; + +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.ContainerTypeDescription; + +import com.raytheon.uf.viz.collaboration.comm.xmpp.XMPPContainer; + +/** + * + * Extends the ECF XMPPContainerInstantiator to create a Viz specific container + * with fixes needed for Viz. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 23, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@SuppressWarnings("restriction") +public class XMPPContainerInstantiator extends + org.eclipse.ecf.internal.provider.xmpp.XMPPContainerInstantiator { + + /** + * Adapted from super.createInstance, only change is that it returns the Viz + * XMPPContainer instead of the ECF XMPPContainer + */ + @Override + public XMPPContainer createInstance(ContainerTypeDescription description, + Object[] args) throws ContainerCreateException { + try { + Integer ka = new Integer(XMPPContainer.DEFAULT_KEEPALIVE); + String name = null; + if (args != null) { + if (args.length > 0) { + name = (String) args[0]; + if (args.length > 1) { + ka = getIntegerFromArg(args[1]); + } + } + } + if (name == null) { + if (ka == null) { + return new XMPPContainer(); + } else { + return new XMPPContainer(ka.intValue()); + } + } else { + if (ka == null) { + ka = new Integer(XMPPContainer.DEFAULT_KEEPALIVE); + } + return new XMPPContainer(name, ka.intValue()); + } + } catch (Exception e) { + throw new ContainerCreateException( + "Exception creating generic container", e); + } + } + +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPContainerPresenceHelper.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPContainerPresenceHelper.java new file mode 100644 index 0000000000..2535686b8f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/XMPPContainerPresenceHelper.java @@ -0,0 +1,494 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp.internal; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.core.user.User; +import org.eclipse.ecf.internal.provider.xmpp.events.IQEvent; +import org.eclipse.ecf.internal.provider.xmpp.events.PresenceEvent; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresenceListener; +import org.eclipse.ecf.presence.IPresenceSender; +import org.eclipse.ecf.presence.roster.IRoster; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.ecf.presence.roster.IRosterItem; +import org.eclipse.ecf.presence.roster.IRosterListener; +import org.eclipse.ecf.presence.roster.IRosterManager; +import org.eclipse.ecf.presence.roster.IRosterSubscriptionListener; +import org.eclipse.ecf.presence.roster.IRosterSubscriptionSender; +import org.eclipse.ecf.provider.xmpp.XMPPContainer; +import org.eclipse.ecf.provider.xmpp.identity.XMPPID; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.RosterPacket; + +/** + * Viz specific implementation of the XMPPContainerPresenceHelper which fixes a + * bug that causes users to disappear from rosters when they log out when they + * are in multiple groups. This class no handles all presence events when a user + * becomes unavaialble, all other events are handled by the ECF version. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 25, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +@SuppressWarnings("restriction") +public class XMPPContainerPresenceHelper extends + org.eclipse.ecf.internal.provider.xmpp.XMPPContainerPresenceHelper { + + /** + * Have our own roster manager to track listeners. + */ + private VizRosterManager rosterManager; + + public XMPPContainerPresenceHelper(XMPPContainer container) { + super(container); + rosterManager = new VizRosterManager(); + } + + /** + * This is overriden because when a roster packet is delivered with a new + * name then the ecf implementation does not change the name, this will + * change it before letting the ecf connection handle the event normally. + */ + @Override + protected void handleIQEvent(IQEvent evt) { + final IQ iq = evt.getIQ(); + if (iq instanceof RosterPacket) { + final RosterPacket rosterPacket = (RosterPacket) iq; + if (rosterPacket.getType() == IQ.Type.SET) { + for (RosterPacket.Item item : rosterPacket.getRosterItems()) { + final RosterPacket.ItemType itemType = item.getItemType(); + if (itemType == RosterPacket.ItemType.to + || itemType == RosterPacket.ItemType.both) { + XMPPID newID = createIDFromName(item.getUser()); + @SuppressWarnings("unchecked") + Collection items = roster.getItems(); + synchronized (items) { + updateRosterName(items, newID, item.getName()); + } + } + } + } + } + super.handleIQEvent(evt); + } + + /** + * Method to recursively find roster entries that match the user id provided + * and change the name of the user in the roster entry. + * + * @param rosterItems + * @param id + * @param name + */ + private void updateRosterName(Collection rosterItems, XMPPID id, + String name) { + if (name == null || name.isEmpty()) { + return; + } + for (Object obj : rosterItems) { + if (obj instanceof IRosterGroup) { + @SuppressWarnings("unchecked") + Collection items = ((IRosterGroup) obj).getEntries(); + synchronized (items) { + updateRosterName(items, id, name); + } + } else if (obj instanceof IRosterEntry) { + IRosterEntry entry = (IRosterEntry) obj; + if (entry.getUser().getID().equals(id)) { + ((User) entry.getUser()).setName(name); + } + } + } + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it can call a custom version of updatePresence when the presence + * type is unavaialble. + */ + @Override + protected void handlePresenceEvent(PresenceEvent evt) { + if (evt.getPresence().getType() == Presence.Type.unavailable) { + final Presence xmppPresence = evt.getPresence(); + final String from = xmppPresence.getFrom(); + final IPresence newPresence = createIPresence(xmppPresence); + final XMPPID fromID = createIDFromName(from); + updatePresence(fromID, newPresence); + rosterManager.notifyPresenceListeners(fromID, newPresence); + } else { + super.handlePresenceEvent(evt); + } + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it can call a custom version of updatePresenceInGroup and + * updatePresenceForMatchingEntry, it also only handles cases of removal. + */ + private void updatePresence(XMPPID fromID, IPresence newPresence) { + @SuppressWarnings("unchecked") + final Collection rosterItems = roster.getItems(); + List newEntrys = new ArrayList(); + synchronized (rosterItems) { + for (final Iterator i = rosterItems.iterator(); i.hasNext();) { + final IRosterItem item = (IRosterItem) i.next(); + if (item instanceof IRosterGroup) { + IRosterEntry[] es = updatePresenceInGroup( + (IRosterGroup) item, fromID, newPresence); + for (int j = 0; j < es.length; j++) { + newEntrys.add(es[j]); + } + } else if (item instanceof org.eclipse.ecf.presence.roster.RosterEntry) { + IRosterEntry entry = updatePresenceForMatchingEntry( + (org.eclipse.ecf.presence.roster.RosterEntry) item, + fromID, newPresence); + if (entry != null) + newEntrys.add(entry); + } + } + } + + IRosterEntry[] entrys = newEntrys.toArray(new IRosterEntry[] {}); + if (entrys.length > 0) { + for (int i = 0; i < entrys.length; i++) { + removeItemFromRoster(rosterItems, fromID); + } + } + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it can call a custom version of updatePresenceForMatchingEntry + */ + private IRosterEntry[] updatePresenceInGroup(IRosterGroup group, + XMPPID fromID, IPresence newPresence) { + List results = new ArrayList(); + @SuppressWarnings("unchecked") + final Collection groupEntries = group.getEntries(); + synchronized (groupEntries) { + for (final Iterator i = groupEntries.iterator(); i + .hasNext();) { + IRosterEntry newEntry = updatePresenceForMatchingEntry( + (org.eclipse.ecf.presence.roster.RosterEntry) i.next(), + fromID, newPresence); + if (newEntry != null) + results.add(newEntry); + } + } + return results.toArray(new IRosterEntry[] {}); + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it can call a custom version of removeEntryFromRoster, it has also + * been simplified to handle only cases of removal when the presence type is + * unavaialble. + */ + private IRosterEntry updatePresenceForMatchingEntry( + org.eclipse.ecf.presence.roster.RosterEntry entry, XMPPID fromID, + IPresence newPresence) { + final IUser user = entry.getUser(); + XMPPID oldID = (XMPPID) user.getID(); + // If the username/host part matches that means we either have to update + // the resource, or create a new client + if (oldID.equals(fromID)) { + return removeEntryFromRoster(oldID, entry, newPresence, user); + } else if (oldID.getUsernameAtHost().equals(fromID.getUsernameAtHost())) { + return entry; + } + return null; + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it can call a custom version of countClientsInRoster, it also uses + * the results of this method differently + */ + private IRosterEntry removeEntryFromRoster(XMPPID oldID, + org.eclipse.ecf.presence.roster.RosterEntry entry, + IPresence newPresence, IUser user) { + if (countClientsInRoster(oldID) > 0) { + // remove this client from roster + return entry; + } else { + // Last one, so we set resource to null and set presence to + // unavailable + oldID.setResourceName(null); + entry.setPresence(newPresence); + rosterManager.notifyRosterUpdate(entry); + return null; + } + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it will return the number of entries that have the same name/hose + * but a different resource. Returning the number of users with same + * name/host even if they have the same resource is what causes the ECF + * version to delete users that are in multiple groups. For a user that is + * not logged in more than once this will always return 0. + */ + private int countClientsInRosterGroup( + org.eclipse.ecf.presence.roster.RosterGroup group, XMPPID oldID) { + @SuppressWarnings("unchecked") + Collection groupItems = group.getEntries(); + int count = 0; + for (final Iterator i = groupItems.iterator(); i.hasNext();) { + final IRosterItem item = (IRosterItem) i.next(); + if (item instanceof org.eclipse.ecf.presence.roster.RosterEntry) { + org.eclipse.ecf.presence.roster.RosterEntry entry = (org.eclipse.ecf.presence.roster.RosterEntry) item; + XMPPID entryID = (XMPPID) entry.getUser().getID(); + if (!entryID.equals(oldID) + && entryID.getUsernameAtHost().equals( + oldID.getUsernameAtHost())) + count++; + } + } + return count; + } + + /** + * This method has been adapted from the ECF XMPPContainerPresenceHelper so + * that it will return the number of entries that have the same name/hose + * but a different resource. Returning the number of users with same + * name/host even if they have the same resource is what causes the ECF + * version to delete users that are in multiple groups. For a user that is + * not logged in more than once this will always return 0. + */ + private int countClientsInRoster(XMPPID oldID) { + @SuppressWarnings("unchecked") + Collection rosterItems = roster.getItems(); + int count = 0; + synchronized (rosterItems) { + for (final Iterator i = rosterItems.iterator(); i.hasNext();) { + final IRosterItem item = (IRosterItem) i.next(); + if (item instanceof org.eclipse.ecf.presence.roster.RosterGroup) { + final org.eclipse.ecf.presence.roster.RosterGroup group = (org.eclipse.ecf.presence.roster.RosterGroup) item; + count += countClientsInRosterGroup(group, oldID); + } else if (item instanceof org.eclipse.ecf.presence.roster.RosterEntry) { + org.eclipse.ecf.presence.roster.RosterEntry entry = (org.eclipse.ecf.presence.roster.RosterEntry) item; + XMPPID entryID = (XMPPID) entry.getUser().getID(); + if (!entryID.equals(oldID) + && entryID.getUsernameAtHost().equals( + oldID.getUsernameAtHost())) { + count++; + } + } + } + } + return count; + } + + private void removeItemFromRoster(Collection rosterItems, + XMPPID itemIDToRemove) { + boolean removed = false; + synchronized (rosterItems) { + for (final Iterator i = rosterItems.iterator(); i.hasNext();) { + final IRosterItem item = (IRosterItem) i.next(); + if (item instanceof org.eclipse.ecf.presence.roster.RosterGroup) { + final org.eclipse.ecf.presence.roster.RosterGroup group = (org.eclipse.ecf.presence.roster.RosterGroup) item; + removed = removeItemFromRosterGroup(group, itemIDToRemove); + // If group is empty, remove it too + if (group.getEntries().size() == 0) + i.remove(); + } else if (item instanceof org.eclipse.ecf.presence.roster.RosterEntry) { + if (((org.eclipse.ecf.presence.roster.RosterEntry) item) + .getUser().getID().equals(itemIDToRemove)) { + i.remove(); + removed = true; + } + } + } + } + if (removed) + rosterManager.notifyRosterUpdate(roster); + + } + + private boolean removeItemFromRosterGroup( + org.eclipse.ecf.presence.roster.RosterGroup group, + XMPPID itemIDToRemove) { + @SuppressWarnings("unchecked") + final Collection groupEntries = group.getEntries(); + synchronized (groupEntries) { + for (final Iterator i = groupEntries.iterator(); i + .hasNext();) { + final org.eclipse.ecf.presence.roster.RosterEntry entry = (org.eclipse.ecf.presence.roster.RosterEntry) i + .next(); + if (entry.getUser().getID().equals(itemIDToRemove)) { + i.remove(); + return true; + } + } + } + return false; + } + + /** + * provide the VizRosterManager access to the super rosterManager + * + * @return + */ + protected IRosterManager getSuperRosterManager() { + return super.getRosterManager(); + } + + /** + * Use the viz roster manager instead of super, most calls are just + * forwarded through. + */ + @Override + public IRosterManager getRosterManager() { + return rosterManager; + } + + /** + * The entire purpose of this class is to intercept the various listeners so + * that they can be notified when presence changes in the viz + * XMPPCOntainerPresenceHelper since it does not have access to the super + * class roster manager listeners. + * + *
+     * 
+     * SOFTWARE HISTORY
+     * 
+     * Date         Ticket#    Engineer    Description
+     * ------------ ---------- ----------- --------------------------
+     * Jul 26, 2012            bsteffen     Initial creation
+     * 
+     * 
+ * + * @author bsteffen + * @version 1.0 + */ + private class VizRosterManager implements IRosterManager { + + private final List rosterUpdateListeners = new ArrayList(); + + private final List presenceListeners = new ArrayList(); + + @Override + @SuppressWarnings("rawtypes") + public Object getAdapter(Class adapter) { + return getSuperRosterManager().getAdapter(adapter); + } + + public void notifyRosterUpdate(IRosterItem entry) { + List toNotify = null; + synchronized (rosterUpdateListeners) { + toNotify = new ArrayList(rosterUpdateListeners); + } + for (IRosterListener l : toNotify) { + l.handleRosterUpdate(entry.getRoster(), entry); + } + } + + public void notifyPresenceListeners(ID fromID, IPresence presence) { + List toNotify = null; + synchronized (presenceListeners) { + toNotify = new ArrayList(presenceListeners); + } + for (IPresenceListener l : toNotify) { + l.handlePresence(fromID, presence); + } + } + + @Override + public IRoster getRoster() { + return getSuperRosterManager().getRoster(); + } + + @Override + public void addRosterListener(IRosterListener listener) { + getSuperRosterManager().addRosterListener(listener); + synchronized (rosterUpdateListeners) { + rosterUpdateListeners.add(listener); + } + } + + @Override + public void removeRosterListener(IRosterListener listener) { + getSuperRosterManager().removeRosterListener(listener); + synchronized (rosterUpdateListeners) { + rosterUpdateListeners.remove(listener); + } + + } + + @Override + public void addRosterSubscriptionListener( + IRosterSubscriptionListener listener) { + getSuperRosterManager().addRosterSubscriptionListener(listener); + } + + @Override + public void removeRosterSubscriptionListener( + IRosterSubscriptionListener listener) { + getSuperRosterManager().removeRosterSubscriptionListener(listener); + } + + @Override + public IRosterSubscriptionSender getRosterSubscriptionSender() { + return getSuperRosterManager().getRosterSubscriptionSender(); + } + + @Override + public IPresenceSender getPresenceSender() { + return getSuperRosterManager().getPresenceSender(); + } + + @Override + public void addPresenceListener(IPresenceListener listener) { + getSuperRosterManager().addPresenceListener(listener); + synchronized (presenceListeners) { + presenceListeners.add(listener); + } + } + + @Override + public void removePresenceListener(IPresenceListener listener) { + getSuperRosterManager().removePresenceListener(listener); + synchronized (presenceListeners) { + presenceListeners.remove(listener); + } + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/smack/ECFConnection.java b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/smack/ECFConnection.java new file mode 100644 index 0000000000..7722529a6c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm.xmpp/src/com/raytheon/uf/viz/collaboration/comm/xmpp/internal/smack/ECFConnection.java @@ -0,0 +1,71 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.xmpp.internal.smack; + +import java.io.IOException; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.provider.comm.IAsynchEventHandler; +import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; +import org.jivesoftware.smack.packet.Presence; + +/** + * Extends ECFConnection from xmpp provider, adds ability to send presence to a + * room using the roomId. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 20, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@SuppressWarnings("restriction") +public class ECFConnection extends + org.eclipse.ecf.internal.provider.xmpp.smack.ECFConnection { + + public ECFConnection(boolean google, Namespace ns, IAsynchEventHandler h) { + super(google, ns, h); + } + + @Override + public void sendPresenceUpdate(ID target, Presence presence) + throws IOException { + if (target instanceof XMPPRoomID) { + // sendPresenceUpdate uses target.getName to determine where to send + // the presence to, this does not work for roomId because getName + // will return the room name without the host, so instead of using + // the super version directly we will setTo on the presence here and + // then send no target to super. + presence.setTo(((XMPPRoomID) target).getMucString()); + super.sendPresenceUpdate(null, presence); + } else { + super.sendPresenceUpdate(target, presence); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/.classpath b/cave/com.raytheon.uf.viz.collaboration.comm/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/.project b/cave/com.raytheon.uf.viz.collaboration.comm/.project new file mode 100644 index 0000000000..99ead76b5b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.comm + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.comm/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..dd47374322 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Feb 24 08:50:10 CST 2012 +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/cave/com.raytheon.uf.viz.collaboration.comm/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.comm/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..de5ba1dde7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/META-INF/MANIFEST.MF @@ -0,0 +1,35 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Collaboratioin +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.comm +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.comm.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.ecf;bundle-version="3.1.300";visibility:=reexport, + org.eclipse.ecf.presence;bundle-version="2.0.0", + org.eclipse.ecf.provider.xmpp;bundle-version="3.2.0", + org.apache.commons.lang;bundle-version="2.3.0", + com.google.guava;bundle-version="1.0.0";visibility:=reexport, + com.raytheon.uf.common.serialization;bundle-version="1.12.1174", + com.raytheon.uf.common.status;bundle-version="1.12.1174", + org.jivesoftware.smack;bundle-version="3.1.100", + org.eclipse.swt;bundle-version="3.6.1", + com.raytheon.uf.common.comm, + com.raytheon.uf.common.localization +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.collaboration.comm, + com.raytheon.uf.viz.collaboration.comm.compression, + com.raytheon.uf.viz.collaboration.comm.identity, + com.raytheon.uf.viz.collaboration.comm.identity.event, + com.raytheon.uf.viz.collaboration.comm.identity.info, + com.raytheon.uf.viz.collaboration.comm.identity.invite, + com.raytheon.uf.viz.collaboration.comm.identity.roster, + com.raytheon.uf.viz.collaboration.comm.identity.user, + com.raytheon.uf.viz.collaboration.comm.provider, + com.raytheon.uf.viz.collaboration.comm.provider.event, + com.raytheon.uf.viz.collaboration.comm.provider.info, + com.raytheon.uf.viz.collaboration.comm.provider.session, + com.raytheon.uf.viz.collaboration.comm.provider.user diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/build.properties b/cave/com.raytheon.uf.viz.collaboration.comm/build.properties new file mode 100644 index 0000000000..34d2e4d2da --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/Activator.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/Activator.java new file mode 100644 index 0000000000..e0b071ee2f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/Activator.java @@ -0,0 +1,83 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.comm.NetworkStatistics; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 27, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ +public class Activator implements BundleActivator { + + public static final String PEER_TO_PEER = "PeerToPeerMsg"; + + public static final String VENUE = "VenueMsg"; + + private static Activator plugin; + + private BundleContext context; + + private NetworkStatistics networkStats = new NetworkStatistics(); + + public BundleContext getContext() { + return context; + } + + /** + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + this.context = bundleContext; + plugin = this; + } + + /** + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + plugin = null; + context = null; + } + + public NetworkStatistics getNetworkStats() { + return networkStats; + } + + public static Activator getDefault() { + return plugin; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/compression/CompressionUtil.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/compression/CompressionUtil.java new file mode 100644 index 0000000000..e7b321a70c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/compression/CompressionUtil.java @@ -0,0 +1,175 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.compression; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.channels.WritableByteChannel; +import java.util.zip.Deflater; +import java.util.zip.DeflaterOutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; +import java.util.zip.InflaterInputStream; + +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; + +/** + * Utilities for compressing or decompressing data. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 11, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class CompressionUtil { + + public static CompressionType COMPRESSION_TYPE = CompressionType.ZLIB; + + private static boolean log_compression = false; + + private enum CompressionType { + ZLIB, GZIP; + + public byte toByte() { + return (byte) ordinal(); + } + + public static CompressionType fromByte(byte b) { + if (b < 0 || b > CompressionType.values().length) { + throw new IndexOutOfBoundsException( + "Unable to determine CompressionType for " + b); + } + return CompressionType.values()[b]; + } + }; + + public static byte[] compress(byte[] bytes) throws CollaborationException { + ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length); + CompressionType cType = COMPRESSION_TYPE; + + out.write(cType.toByte()); + OutputStream compressionStrm = null; + try { + compressionStrm = createCompressionOutputStream(out); + long start = System.currentTimeMillis(); + compressionStrm.write(bytes); + compressionStrm.flush(); + compressionStrm.close(); + byte[] result = out.toByteArray(); + if (log_compression) { + System.out.println(cType + " Compression time(milliseconds) " + + (System.currentTimeMillis() - start) / 1000F + + " to compress " + bytes.length + " bytes to " + + result.length + " bytes."); + } + return result; + } catch (IOException e) { + throw new CollaborationException("Unable to compress data.", e); + } + } + + private static OutputStream createCompressionOutputStream(OutputStream out) + throws IOException { + OutputStream stream = null; + switch (COMPRESSION_TYPE) { + case GZIP: + stream = new GZIPOutputStream(out); + break; + case ZLIB: + default: + Deflater defl = new Deflater(Deflater.BEST_COMPRESSION); + stream = new DeflaterOutputStream(out, defl); + break; + } + return stream; + } + + public static byte[] uncompress(byte[] bytes) throws CollaborationException { + ByteArrayInputStream in = new ByteArrayInputStream(bytes); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + CompressionType cType = CompressionType.fromByte((byte) in.read()); + long start = System.currentTimeMillis(); + + try { + ReadableByteChannel src = Channels + .newChannel(createCompressionInputStream(cType, in)); + WritableByteChannel dest = Channels.newChannel(out); + + final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024); + while (src.read(buffer) != -1) { + buffer.flip(); + dest.write(buffer); + buffer.compact(); + } + + // EOF will leave buffer in fill state + buffer.flip(); + + // make sure the buffer is fully drained. + while (buffer.hasRemaining()) { + dest.write(buffer); + } + dest.close(); + byte[] resultBuffer = out.toByteArray(); + if (log_compression) { + System.out.println(cType + + " Uncompression time(milliseconds): " + + ((System.currentTimeMillis() - start) / 1000F) + + " to uncompress " + bytes.length + " bytes to " + + resultBuffer.length + " bytes."); + } + return resultBuffer; + } catch (IOException e) { + throw new CollaborationException("Unable to uncompress data.", e); + } + } + + private static InputStream createCompressionInputStream( + CompressionType cType, InputStream in) throws IOException { + InputStream stream = null; + switch (cType) { + case GZIP: + stream = new GZIPInputStream(in); + break; + case ZLIB: + default: + stream = new InflaterInputStream(in); + break; + } + return stream; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/CollaborationException.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/CollaborationException.java new file mode 100644 index 0000000000..7d92652551 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/CollaborationException.java @@ -0,0 +1,73 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class CollaborationException extends Exception { + + private static final long serialVersionUID = 2897604473798379699L; + + /** + * + */ + public CollaborationException() { + + } + + /** + * @param message + */ + public CollaborationException(String message) { + super(message); + } + + /** + * + * @param message + * @param cause + */ + public CollaborationException(String message, Throwable cause) { + super(message, cause); + } + + /** + * @param cause + */ + public CollaborationException(Throwable cause) { + super(cause); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IAccountManager.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IAccountManager.java new file mode 100644 index 0000000000..79d504feea --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IAccountManager.java @@ -0,0 +1,130 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import java.util.Map; + +import org.eclipse.ecf.presence.IPresence; + +import com.raytheon.uf.viz.collaboration.comm.identity.roster.ISubscriptionResponder; + +/** + * TODO Add Description + * + * + * + * + *
    + * EventBus subscription events. + *
  • ISubscriptionResponseEvent : This event is posted when a subscription + * request has been responded to.
  • + *
+ * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IAccountManager { + + /** + * Set whether the account manager will auto subscribe to subscription + * requests. + * + * @param mode + * The auto subscription mode. + */ + void setAutoSubscriptionMode(boolean mode); + + /** + * Get the account manager auto subscription mode. + * + * @return The auto subscription mode. + */ + boolean getAutoSubscriptionMode(); + + /** + * + * @param responder + */ + void setSubscriptionRequestResponder(ISubscriptionResponder responder); + + /** + * Removes the current subscription request responder. + */ + void removeSubscriptionRequestResponder(); + + /** + * + * @param name + * @param password + * @param attributes + * @throws CollaborationException + */ + void createAccount(String name, char[] password, + Map attributes) throws CollaborationException; + + /** + * Allows the user to change their account password. If the server does not + * allow this operation an exception will be thrown. + * + * @param password + * @throws CollaborationException + */ + void changePassword(char[] password) throws CollaborationException; + + /** + * Allows the user to delete this account on the server. An exception will + * be thrown if the account deletion fails. If the account is currently + * connected, it and any associated objects will be closed followed by the + * account deletion. + * + * @throws CollaborationException + */ + void deleteAccount() throws CollaborationException; + + /** + * Can an account be created on the server. + * + * @return Can an account be created on the server? + * @throws CollaborationException + * The query failed. + */ + boolean canCreateAccount() throws CollaborationException; + + /** + * Allow the user to send presence information to the transport provider. + * + * @param presence + * @return Return status information. + * @throws CollaborationException + */ + public void sendPresence(IPresence presence) throws CollaborationException; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ICollaborationMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ICollaborationMessage.java new file mode 100644 index 0000000000..0e1b7b021a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ICollaborationMessage.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 19, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ICollaborationMessage extends IMessage { + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IMessage.java new file mode 100644 index 0000000000..3706886387 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IMessage.java @@ -0,0 +1,136 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IMessage extends IPropertied { + + public enum MessageType { CHAT, COLLABORATION }; + + static final String MESSAGE_TYPE = "type"; + + static final String TIMESTAMP = "timestamp"; + + /** + * @return the to + */ + IQualifiedID getTo(); + + /** + * @param to + * the to to set + */ + void setTo(IQualifiedID to); + + /** + * @return the from + */ + IQualifiedID getFrom(); + + /** + * @param from + * the from to set + */ + void setFrom(IQualifiedID from); + + /** + * Get the subject of this message. + * @return The subject of this message. The subject may be null. + */ + String getSubject(); + + /** + * Set the subject of this message. If not set the + * subject is set to null. + * @param subject The subject of this message. + */ + void setSubject(String subject); + + /** + * + * @return + */ + MessageType getMessageType(); + + /** + * Get the body of this message. + * @return The body of this message. The body may be null. + */ + String getBody(); + + /** + * Set the data to be transmitted in the message. If not set the + * body is set to null. + * @param body The data to be transmitted in the message. + */ + void setBody(String body); + + /** + * Returns the body of the message as a byte array. + * @return The body of the message as binary data. + */ + byte [] getBodyAsBinary(); + + /** + * Set the body of the message as a byte array. + * @param body The binary data to be transmitted in the message. + */ + void getBodyAsBinary(byte [] body); + + /** + * Get the status of this message. + * @return The message status. + */ + String getStatus(); + + /** + * Set the status of this message. + * @param The message status. + */ + void setStatus(String status); + + + /** + * Get the receipt time for this message in milliseconds from + * Jan 1, 1970. + * @return The receipt time stamp. + */ + long getTimeStamp(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IPeerToPeer.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IPeerToPeer.java new file mode 100644 index 0000000000..1debda9b0f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IPeerToPeer.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IPeerToPeer extends ISession, IEventPublisher { + + /** + * Send a Text message. Note that the recipient of the message is included + * as an attribute of the message. + * + * @param message + */ + void sendPeerToPeer(IMessage message) throws CollaborationException; + + /** + * Send a Text message to a specific receiver. + * + * @param to + * The intended receiver. + * @param message + * The message to send. + */ + void sendPeerToPeer(IQualifiedID to, String message) + throws CollaborationException; + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IPropertied.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IPropertied.java new file mode 100644 index 0000000000..513717ec09 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IPropertied.java @@ -0,0 +1,153 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import java.util.Collection; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 27, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IPropertied { + + public static class Property { + private String value; + + private String key; + + /** + * + * @param key + * @param value + */ + public Property(String key, String value) { + this.key = key; + this.value = value; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + } + + /** + * @return the key + */ + public String getKey() { + return key; + } + + /** + * @param key the key to set + */ + public void setKey(String key) { + this.key = key; + } + + @Override + public String toString() { + return String.format("[%s{%s}]", key, value); + } + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Property other = (Property) obj; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + } + + /** + * + * @param key + * @param defaultValue + * @return + */ + void setProperty(String key, String value); + + /** + * + * @param key + * @param defaultValue + * @return + */ + String getProperty(String key, String defaultValue); + + /** + * Gets the message properties as a collection of key, value + * pairs. Always returns a not-null value. + * @return + */ + Collection getProperties(); + + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ISession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ISession.java new file mode 100644 index 0000000000..12781442ad --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ISession.java @@ -0,0 +1,96 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + * + * Implementations of ISession do not support polling for messages but instead + * make exclusive use of listener based callbacks to make incoming data + * available. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ISession extends IEventPublisher { + + /** + * Close and clean up this session. After a close, isConnected must return + * false. + */ + public void close(); + + /** + * + * @return + */ + public UserId getUserID(); + + /** + * Gets the connection status of the session. + * + * @return The connection status. + */ + public boolean isConnected(); + + /** + * Get the session identifier. + * + * @return The session identifier. + */ + public String getSessionId(); + + public CollaborationConnection getConnection(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ISharedDisplaySession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ISharedDisplaySession.java new file mode 100644 index 0000000000..3353f4bfb5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/ISharedDisplaySession.java @@ -0,0 +1,133 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * + * + *
    + *
  • EventBus subscription events. Implementors may to post the following + * events.
  • + *
      + *
    • IVenueParticipantEvent : This event is posted when a + * venue participant enters, leaves a venue, or updates their status in the + * venue.
    • + *
    • TextMessage : Text messages send between users. Meant to + * be displayed as conversation.
    • + *
    • IDisplayEvent : These messages are CAVE to CAVE events
    • + *
    • IRenderable : These messages are CAVE to CAVE + * display......
    • + *
    • IInitData : These messages are CAVE to CAVE + * initialization data......
    • + *
    • IDisplayEvent : These messages are CAVE to CAVE + * display......
    • + * + *
    + *
+ * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ISharedDisplaySession extends IVenueSession { + + /** + * Sends the object to the other collaborators on the session. The object + * must be serializable and once received by the others, will be posted to + * the session's event bus. + * + * @param obj + * the serializable object to send + * @throws CollaborationException + */ + public void sendObjectToVenue(Object obj) throws CollaborationException; + + /** + * Sends the object to a specific collaborator on the session. The object + * must be serializable and once received by the other, will be posted to + * the session's event bus. + * + * @param id + * the id of the collaborator to send to + * @param obj + * the serializable object to send + * @throws CollaborationException + */ + public void sendObjectToPeer(IQualifiedID id, Object obj) + throws CollaborationException; + + /** + * Returns the current Data Provider for the session + * + * @return + */ + public UserId getCurrentDataProvider(); + + /** + * Returns the current Session Leader for the session + * + * @return + */ + public UserId getCurrentSessionLeader(); + + /** + * Sets the current Data Provider for the session + * + * @param participant + */ + public void setCurrentDataProvider(UserId participant); + + /** + * Sets the current Session Leader for the session + * + * @param participant + */ + public void setCurrentSessionLeader(UserId participant); + + /** + * Checks if the currently logged in user has the role on this session + * + * @param role + * @return + */ + public boolean hasRole(SharedDisplayRole role); + + /** + * Gets the connection status of the session. + * + * @return The connection status. + */ + public boolean isConnected(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IVenueMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IVenueMessage.java new file mode 100644 index 0000000000..164d4a6a51 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IVenueMessage.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 19, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenueMessage extends IMessage { + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IVenueSession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IVenueSession.java new file mode 100644 index 0000000000..a5f0ed61cb --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/IVenueSession.java @@ -0,0 +1,109 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +import java.util.List; + +import org.eclipse.ecf.presence.IPresence; + +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * + * + *
    + *
  • EventBus subscription events. Implementors are required to post the + * following events.
  • + *
      + *
    • IVenueParticipantEvent : This event is posted when a + * venue participant enters, leaves a venue, or updates their status in the + * venue.
    • + *
    • TextMessage : Text messages send between users. Meant to + * be displayed as conversation.
    • + *
    • CollaborationMessage : These messages are CAVE to CAVE + * command messages.
    • + *
    + *
+ * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 5, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenueSession extends ISession { + + /** + * Returns information about a venue. + * + * @return Information about a venue + */ + public IVenue getVenue(); + + /** + * Send a chat message. + * + * @param message + * The message to send. + */ + public void sendChatMessage(String message) throws CollaborationException; + + /** + * Send an invitation from this venue to another user. + * + * @param id + * The target user for this invitation. + * @param subject + * The intended subject of the venue conversation. + * @return + */ + public void sendInvitation(UserId id, VenueInvite invite) + throws CollaborationException; + + /** + * Send an invitation from this venue to a list of users. + * + * @param ids + * A list of target users for this invitation. + * @param body + * Any text that the user may wish to include. + * @return + */ + public void sendInvitation(List ids, VenueInvite invite) + throws CollaborationException; + + /** + * Send presence to a venue. + * + * @param presence + */ + public void sendPresence(IPresence presence) throws CollaborationException; + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/MultipleLoginException.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/MultipleLoginException.java new file mode 100644 index 0000000000..667b8bedff --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/MultipleLoginException.java @@ -0,0 +1,51 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +/** + * If a user is logged in one CAVE and tries to login from another this + * exception gets thrown as that is not supported. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 9, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class MultipleLoginException extends CollaborationException { + private static final long serialVersionUID = 3124620509180835631L; + + /** + * @param message + * @param cause + */ + public MultipleLoginException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/UsernamePasswordException.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/UsernamePasswordException.java new file mode 100644 index 0000000000..4bced873f6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/UsernamePasswordException.java @@ -0,0 +1,51 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class UsernamePasswordException extends CollaborationException { + + private static final long serialVersionUID = 3124620509180835631L; + + /** + * @param message + * @param cause + */ + public UsernamePasswordException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IEventPublisher.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IEventPublisher.java new file mode 100644 index 0000000000..5a01c69ba5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IEventPublisher.java @@ -0,0 +1,47 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            jkorman     Initial creation
+ * Jun 12, 2012             njensen      Improved
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IEventPublisher { + + public void registerEventHandler(Object handler); + + public void unregisterEventHandler(Object handler); + + public void postEvent(Object event); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IHttpdCollaborationConfigurationEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IHttpdCollaborationConfigurationEvent.java new file mode 100644 index 0000000000..53c11497d8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IHttpdCollaborationConfigurationEvent.java @@ -0,0 +1,47 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 11, 2012            bkowal     Initial creation
+ *
+ * 
+ * + * @author bkowal + * @version 1.0 + */ + +public interface IHttpdCollaborationConfigurationEvent { + + /** + * + * @return the url used to connect to the collaboration + * httpd server. + */ + String getHttpdCollaborationURL(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IHttpdXmppMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IHttpdXmppMessage.java new file mode 100644 index 0000000000..7040c44636 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IHttpdXmppMessage.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +import java.util.regex.Pattern; + +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; + +/** + * Used to store constants that are used to validate, analyze, and parse status + * and configuration messages associated with the AWIPS II httpd collaboration + * server. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 7, 2012            bkowal     Initial creation
+ * 
+ * 
+ * + * @author bkowal + * @version 1.0 + */ + +public interface IHttpdXmppMessage { + // Constant Strings + public static final String URL_PARAMETER_NAME = "sessionDataHttpURL"; + + public static final String ERROR_PARAMETER_NAME = "error"; + + // Regex + static final String PREABMLE_REGEX = Tools.CONFIG_PREAMBLE.replace("[", + "\\["); + + static final String SUFFIX_REGEX = " : .+" + Tools.DIRECTIVE_SUFFIX; + + static final String COLLABORATION_URL_REGEX = "http://.+:[1-9][0-9]*/session_data/"; + + // Regex Patterns + public static final Pattern configErrorPattern = Pattern + .compile(PREABMLE_REGEX + ERROR_PARAMETER_NAME + SUFFIX_REGEX); + + public static final Pattern configURLPattern = Pattern + .compile(PREABMLE_REGEX + URL_PARAMETER_NAME + SUFFIX_REGEX); + + public static final Pattern urlPattern = Pattern + .compile(COLLABORATION_URL_REGEX); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IRosterChangeEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IRosterChangeEvent.java new file mode 100644 index 0000000000..c831a2abc6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IRosterChangeEvent.java @@ -0,0 +1,57 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +import org.eclipse.ecf.presence.roster.IRosterItem; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 6, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IRosterChangeEvent { + + /** + * Get the event type. + * + * @return The event type. + */ + RosterChangeType getType(); + + /** + * Get the changed entry + * + * @return The changed entry. + */ + IRosterItem getItem(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ISubscriptionResponseEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ISubscriptionResponseEvent.java new file mode 100644 index 0000000000..8ea8de9a0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ISubscriptionResponseEvent.java @@ -0,0 +1,57 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +import org.eclipse.ecf.presence.IPresence; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ISubscriptionResponseEvent { + + /** + * How was the subscription responded to. + * + * @return The response type. + */ + IPresence.Type getResponse(); + + /** + * Was this response due to an auto responder. + * + * @return Was this response due to an auto responder. + */ + boolean isAutoResponder(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ITextMessageEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ITextMessageEvent.java new file mode 100644 index 0000000000..ec34f05d93 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ITextMessageEvent.java @@ -0,0 +1,49 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 27, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ITextMessageEvent { + + /** + * + * @return + * + */ + TextMessage getMessage(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IVenueInvitationEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IVenueInvitationEvent.java new file mode 100644 index 0000000000..5cb4f0e07b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IVenueInvitationEvent.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * Encapsulates a venue invitation to the user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenueInvitationEvent { + + /** + * + * @return + */ + IQualifiedID getRoomId(); + + /** + * + * @return + */ + IQualifiedID getInviter(); + + /** + * + */ + String getSubject(); + + public VenueInvite getInvite(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IVenueParticipantEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IVenueParticipantEvent.java new file mode 100644 index 0000000000..dc66178d10 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/IVenueParticipantEvent.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +import org.eclipse.ecf.presence.IPresence; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 20, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenueParticipantEvent { + + /** + * + * @return + */ + ParticipantEventType getEventType(); + + /** + * + * @return + */ + UserId getParticipant(); + + /** + * + * @return + */ + IPresence getPresence(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ParticipantEventType.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ParticipantEventType.java new file mode 100644 index 0000000000..38b52d20d0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/ParticipantEventType.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 20, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public enum ParticipantEventType { + ARRIVED, DEPARTED, UPDATED, PRESENCE_UPDATED; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/RosterChangeType.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/RosterChangeType.java new file mode 100644 index 0000000000..9a70f8528c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/event/RosterChangeType.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.event; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 11, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public enum RosterChangeType { + ADD, DELETE, MODIFY, PRESENCE +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java new file mode 100644 index 0000000000..924c9dff95 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenue.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.info; + +import java.util.Collection; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * Provides information about a venue. In addition implementations will act as a + * target for participant updates such as + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenue { + + /** + * + * @return + */ + public IVenueInfo getInfo(); + + /** + * + * @return + */ + public Collection getParticipants(); + + /** + * Get the presence for a user in the session. + * + * @param user + * @return + */ + public IPresence getPresence(IUser user); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenueInfo.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenueInfo.java new file mode 100644 index 0000000000..6b3f73fb22 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/IVenueInfo.java @@ -0,0 +1,91 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.info; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenueInfo { + + /** + * + * @return + */ + String getVenueDescription(); + + /** + * Get a long name for venue + * + * @return + */ + String getVenueName(); + + /** + * + * @return + */ + String getVenueSubject(); + + /** + * + * @return + */ + String getVenueID(); + + /** + * Get a count of the current number of room participants + * + * @return Count of the current number of room participants + */ + int getParticipantCount(); + + /** + * + * @return + */ + boolean isModerated(); + + /** + * + * @return + */ + boolean isPersistent(); + + /** + * + * @return + */ + boolean requiresPassword(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/SiteConfigInformation.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/SiteConfigInformation.java new file mode 100644 index 0000000000..caa53e5db0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/info/SiteConfigInformation.java @@ -0,0 +1,187 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.info; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 12, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +public class SiteConfigInformation { + + public static final String ROLE_NAME = "Role"; + + public static final String SITE_NAME = "Site"; + + @XmlElement + private List server; + + @XmlElement + private List config; + + /** + * @return the hosts + */ + public List getServer() { + return server; + } + + /** + * @param hosts + * the hosts to set + */ + public void setServer(List server) { + this.server = server; + } + + /** + * @return the infos + */ + public List getConfig() { + return config; + } + + /** + * @param infos + * the infos to set + */ + public void setConfig(List config) { + this.config = config; + } + + @XmlAccessorType(XmlAccessType.NONE) + public static class HostConfig { + @XmlAttribute + private String hostname; + + @XmlAttribute + private String prettyName; + + /** + * @return the hostname + */ + public String getHostname() { + return hostname; + } + + /** + * @param hostname + * the hostname to set + */ + public void setHostname(String hostname) { + this.hostname = hostname; + } + + /** + * @return the prettyName + */ + public String getPrettyName() { + return prettyName; + } + + /** + * @param prettyName + * the prettyName to set + */ + public void setPrettyName(String prettyName) { + this.prettyName = prettyName; + } + } + + @XmlAccessorType(XmlAccessType.NONE) + public static class SiteConfig { + + @XmlAttribute + private String site; + + @XmlElement + private String[] subscribedSites; + + @XmlElement + private String[] roles; + + /** + * @return the site + */ + public String getSite() { + return site; + } + + /** + * @param site + * the site to set + */ + public void setSite(String site) { + this.site = site; + } + + /** + * @return the subscribedSites + */ + public String[] getSubscribedSites() { + return subscribedSites; + } + + /** + * @param subscribedSites + * the subscribedSites to set + */ + public void setSubscribedSites(String[] subscribedSites) { + this.subscribedSites = subscribedSites; + } + + /** + * @return the role + */ + public String[] getRoles() { + return roles; + } + + /** + * @param role + * the role to set + */ + public void setRoles(String[] roles) { + this.roles = roles; + } + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/ColorPopulator.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/ColorPopulator.java new file mode 100644 index 0000000000..11322ead92 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/ColorPopulator.java @@ -0,0 +1,148 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.invite; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 19, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class ColorPopulator { + @DynamicSerializeElement + private List userName; + + @DynamicSerializeElement + private List red; + + @DynamicSerializeElement + private List green; + + @DynamicSerializeElement + private List blue; + + public ColorPopulator() { + } + + public ColorPopulator(Map rgbs) { + userName = new ArrayList(); + red = new ArrayList(); + green = new ArrayList(); + blue = new ArrayList(); + for (UserId key : rgbs.keySet()) { + userName.add(key); + red.add(rgbs.get(key).red); + green.add(rgbs.get(key).green); + blue.add(rgbs.get(key).blue); + } + } + + public Map getColors() { + Map colors = new HashMap(); + for (int i = 0; i < userName.size(); i++) { + colors.put(userName.get(i), + new RGB(red.get(i), green.get(i), blue.get(i))); + } + return colors; + } + + /** + * @return the userName + */ + public List getUserName() { + return userName; + } + + /** + * @param userName + * the userName to set + */ + public void setUserName(List userName) { + this.userName = userName; + } + + /** + * @return the red + */ + public List getRed() { + return red; + } + + /** + * @param red + * the red to set + */ + public void setRed(List red) { + this.red = red; + } + + /** + * @return the green + */ + public List getGreen() { + return green; + } + + /** + * @param green + * the green to set + */ + public void setGreen(List green) { + this.green = green; + } + + /** + * @return the blue + */ + public List getBlue() { + return blue; + } + + /** + * @param blue + * the blue to set + */ + public void setBlue(List blue) { + this.blue = blue; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/SharedDisplayVenueInvite.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/SharedDisplayVenueInvite.java new file mode 100644 index 0000000000..4ccc65240d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/SharedDisplayVenueInvite.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.invite; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 19, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class SharedDisplayVenueInvite extends VenueInvite { + + @DynamicSerializeElement + private UserId sessionLeader; + + @DynamicSerializeElement + private UserId dataProvider; + + public UserId getSessionLeader() { + return sessionLeader; + } + + public void setSessionLeader(UserId sessionLeader) { + this.sessionLeader = sessionLeader; + } + + public UserId getDataProvider() { + return dataProvider; + } + + public void setDataProvider(UserId dataProvider) { + this.dataProvider = dataProvider; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/VenueInvite.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/VenueInvite.java new file mode 100644 index 0000000000..951ded41dd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/invite/VenueInvite.java @@ -0,0 +1,77 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.invite; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * An invite message for inviting another user to a venue. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +@DynamicSerialize +public class VenueInvite { + + @DynamicSerializeElement + private String subject; + + @DynamicSerializeElement + private String message; + + @DynamicSerializeElement + private String sessionId; + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/roster/ISubscriptionResponder.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/roster/ISubscriptionResponder.java new file mode 100644 index 0000000000..4fa37429bd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/roster/ISubscriptionResponder.java @@ -0,0 +1,64 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.roster; + +import org.eclipse.ecf.presence.IPresence; + +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ISubscriptionResponder { + + /** + * + * @param fromID + * @return The response that should be returned to the subscriber. + */ + IPresence.Type handleSubscribeRequest(IQualifiedID fromID); + + /** + * + * @param fromID + */ + void handleSubscribed(IQualifiedID fromID); + + /** + * + * @param fromID + */ + void handleUnsubscribed(IQualifiedID fromID); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/ID.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/ID.java new file mode 100644 index 0000000000..0692cb3491 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/ID.java @@ -0,0 +1,58 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.user; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 27, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface ID { + + /** + * + * @param userName + */ + void setName(String userName); + + /** + * + */ + String getName(); + + /** + * + * @return + */ + String getFQName(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/IQualifiedID.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/IQualifiedID.java new file mode 100644 index 0000000000..57d65667b3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/IQualifiedID.java @@ -0,0 +1,65 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.user; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IQualifiedID extends ID { + + /** + * + * @param hostName + */ + void setHost(String hostName); + + /** + * + * @return + */ + String getHost(); + + /** + * + * @param resource + */ + void setResource(String resource); + + /** + * + * @return + */ + String getResource(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/IVenueId.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/IVenueId.java new file mode 100644 index 0000000000..f6e8677f28 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/IVenueId.java @@ -0,0 +1,43 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.user; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 29, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public interface IVenueId extends IQualifiedID { + + String getVenueName(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/SharedDisplayRole.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/SharedDisplayRole.java new file mode 100644 index 0000000000..bffbcdaab1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/identity/user/SharedDisplayRole.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.identity.user; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 22, 2012            jkorman     Initial creation
+ *
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public enum SharedDisplayRole { + DATA_PROVIDER, SESSION_LEADER, PARTICIPANT; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/BaseMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/BaseMessage.java new file mode 100644 index 0000000000..ba9a68a6ec --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/BaseMessage.java @@ -0,0 +1,251 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public abstract class BaseMessage implements Serializable, IMessage { + + private static final long serialVersionUID = 1L; + + private Map properties = null; + + private String body; + + private IQualifiedID to; + + private IQualifiedID from; + + private String subject; + + private String status; + + private long timeStamp; + + /** + * + * @param to + * @param body + */ + protected BaseMessage(IQualifiedID to, String body) { + this.body = body; + this.to = to; + initProperties(); + timeStamp = setCurrentTimeStamp(); + } + + /** + * @return the to + */ + @Override + public IQualifiedID getTo() { + return to; + } + + /** + * @param to + * the to to set + */ + @Override + public void setTo(IQualifiedID to) { + this.to = to; + } + + /** + * @return the from + */ + @Override + public IQualifiedID getFrom() { + return from; + } + + /** + * @param from + * the from to set + */ + @Override + public void setFrom(IQualifiedID from) { + this.from = from; + } + + /** + * @param body + * the body to set + */ + @Override + public void setBody(String body) { + this.body = body; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getBody() + */ + @Override + public String getBody() { + return body; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getBodyAsBinary() + */ + @Override + public byte[] getBodyAsBinary() { + return null; + } + + /** + * + */ + private void initProperties() { + if (properties == null) { + properties = new HashMap(); + } + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#setProperty(java.lang.String, + * java.lang.String) + */ + @Override + public void setProperty(String key, String value) { + properties.put(key, value); + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getProperty(java.lang.String, + * java.lang.String) + */ + @Override + public String getProperty(String key, String defaultValue) { + String retValue = defaultValue; + if (properties != null) { + if (properties.containsKey(key)) { + retValue = properties.get(key); + } + } + return retValue; + } + + /** + * Gets the message properties as a collection of key, value pairs. Always + * returns a not-null value. + * + * @return A Collection of properties associated with this message. + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getProperties() + */ + @Override + public Collection getProperties() { + Collection p = new ArrayList(); + for (String s : properties.keySet()) { + p.add(new Property(s, properties.get(s))); + } + return p; + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getSubject() + */ + @Override + public String getSubject() { + return subject; + } + + /** + * + * @param subject + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#setSubject(java.lang.String) + */ + @Override + public void setSubject(String subject) { + this.subject = subject; + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getStatus() + */ + @Override + public String getStatus() { + return status; + } + + /** + * + * @param status + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#setStatus(java.lang.String) + */ + @Override + public void setStatus(String status) { + this.status = status; + } + + /** + * Get the receipt time for this message in milliseconds from Jan 1, 1970. + * + * @return The receipt time stamp. + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getTimeStamp() + */ + @Override + public long getTimeStamp() { + return timeStamp; + } + + /** + * + * @return + */ + public void setTimeStamp(long timeStamp) { + this.timeStamp = timeStamp; + } + + private long setCurrentTimeStamp() { + long timestamp = System.currentTimeMillis(); + properties.put(TIMESTAMP, Long.toHexString(timestamp)); + return timestamp; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/CollaborationMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/CollaborationMessage.java new file mode 100644 index 0000000000..657342dd20 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/CollaborationMessage.java @@ -0,0 +1,71 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider; + +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class CollaborationMessage extends BaseMessage { + + private static final long serialVersionUID = 1L; + + /** + * + * @param to + * @param body + */ + public CollaborationMessage(IQualifiedID to, String body) { + super(to, body); + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getMessageType() + */ + @Override + public MessageType getMessageType() { + return MessageType.COLLABORATION; + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IMessage#getBodyAsBinary(byte[]) + */ + @Override + public void getBodyAsBinary(byte[] body) { + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/SerializationMode.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/SerializationMode.java new file mode 100644 index 0000000000..cc624dcc5d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/SerializationMode.java @@ -0,0 +1,74 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider; + +import java.io.Serializable; +import java.lang.annotation.Annotation; + +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; + +/** + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 23, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public enum SerializationMode { + THRIFT, JAXB, JAVA, STRING, NONE, ISNULL; + + public static SerializationMode getMode(Object object) { + SerializationMode mode = ISNULL; + if (object != null) { + if (object instanceof String) { + mode = STRING; + } else if (object instanceof Serializable) { + mode = JAVA; + } else { + // We may override the serialization type + Class clazz = object.getClass(); + Annotation a = clazz.getAnnotation(DynamicSerialize.class); + if (a != null) { + mode = THRIFT; + } else { + a = clazz.getAnnotation(XmlRootElement.class); + if (a != null) { + mode = JAXB; + } else { + mode = NONE; + } + } + } + } + return mode; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/TextMessage.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/TextMessage.java new file mode 100644 index 0000000000..e0270cd0ad --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/TextMessage.java @@ -0,0 +1,66 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider; + +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class TextMessage extends BaseMessage { + + private static final long serialVersionUID = 1L; + + /** + * + * @param to + * @param body + */ + public TextMessage(IQualifiedID to, String body) { + super(to, body); + } + + /** + * + */ + @Override + public MessageType getMessageType() { + return MessageType.CHAT; + } + + @Override + public void getBodyAsBinary(byte[] body) { + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/Tools.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/Tools.java new file mode 100644 index 0000000000..665ef5ba53 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/Tools.java @@ -0,0 +1,389 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider; + +import javax.xml.bind.JAXBException; + +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.util.Base64; + +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.viz.collaboration.comm.compression.CompressionUtil; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 7, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public abstract class Tools { + + public static final String TAG_INVITE = "[[INVITEID#"; + + public static final String TAG_INVITE_ID = TAG_INVITE + "%s]]%s"; + + public static final String PROP_SESSION_ID = "sessionId"; + + public static final String CMD_PREAMBLE = "[[COMMAND#"; + + public static final String CONFIG_PREAMBLE = "[[CONFIG#"; + + public static final String DIRECTIVE_SUFFIX = "]]"; + + private static final String ENV_THRIFT = CMD_PREAMBLE + + SerializationMode.THRIFT.name() + "]]"; + + private static final String ENV_THRIFT_COMPRESSED = CMD_PREAMBLE + + SerializationMode.THRIFT.name() + "-COMPRESSED]]"; + + private static final String ENV_JAXB = CMD_PREAMBLE + + SerializationMode.JAXB.name() + "]]"; + + private static final String ENV_JAXB_COMPRESSED = CMD_PREAMBLE + + SerializationMode.JAXB.name() + "-COMPRESSED]]"; + + private static final String ENV_STRING = CMD_PREAMBLE + + SerializationMode.STRING.name() + "]]"; + + private static final String ENV_JAVA = CMD_PREAMBLE + + SerializationMode.JAVA.name() + "]]"; + + private static final String ENV_NONE = CMD_PREAMBLE + + SerializationMode.NONE.name() + "]]"; + + public static final String VENUE_SUBJECT_PROP = "subject"; + + public static final String NAME_DELIM = "@"; + + public static final String PORT_DELIM = ":"; + + public static final String RESOURCE_DELIM = "/"; + + public static boolean COMPRESSION_OFF = false; + + static { + try { + COMPRESSION_OFF = Boolean + .getBoolean("collaboration.compressionOff"); + } catch (Exception e) { + // must not have permission to access system properties. ignore and + // use default. + } + } + + /** + * + * @param + * @param container + * @param c + * @return + */ + @SuppressWarnings("unchecked") + public static T getPresenceContainerAdapter(IContainer container, + Class c) { + return (T) container.getAdapter(c); + } + + /** + * + * @param id + * @return + */ + public static String parseName(String id) { + String name = null; + if (id != null) { + int delimPos = id.indexOf(NAME_DELIM); + if (delimPos >= 0) { + name = id.substring(0, delimPos); + } + } + return name; + } + + /** + * + * @param id + * @return + */ + public static String parseHost(String id) { + String host = null; + if (id != null) { + int delimPos = id.indexOf(NAME_DELIM); + if (delimPos >= 0) { + // Ok we have the start of the host name + int start = delimPos + 1; + int stop = start; + delimPos = id.indexOf(PORT_DELIM); + if (delimPos > stop) { + // ok we have a port so grab anything in between + stop = delimPos; + } else { + // no port delimiter, so check for the resource + delimPos = id.indexOf(RESOURCE_DELIM); + if (delimPos > stop) { + // we have the resource delimiter + stop = delimPos; + } else { + stop = id.length(); + } + } + host = id.substring(start, stop); + } + } + return host; + } + + /** + * + * @param id + * @return + */ + public static String parsePort(String id) { + String host = null; + if (id != null) { + int delimPos = id.indexOf(NAME_DELIM); + if (delimPos >= 0) { + // Ok we have the start of the host name + int start = delimPos + 1; + int stop = start; + delimPos = id.indexOf(PORT_DELIM); + if (delimPos > stop) { + // ok we have a port so grab anything in between + start = delimPos + 1; + delimPos = id.indexOf(RESOURCE_DELIM); + if (delimPos > start) { + stop = delimPos; + } else { + stop = id.length(); + } + host = id.substring(start, stop); + } + } + } + return host; + } + + /** + * + * @param id + * @return + */ + public static String parseResource(String id) { + String resource = null; + if (id != null) { + int delimPos = id.indexOf(NAME_DELIM); + // Ensure that the name delimiter is there first. + if (delimPos >= 0) { + int start = delimPos + 1; + delimPos = id.indexOf(RESOURCE_DELIM); + if (delimPos > start) { + delimPos++; + if (delimPos < id.length()) { + resource = id.substring(delimPos); + } + } + } + } + return resource; + } + + /** + * Decode Base64 encoded String data into a byte array. + * + * @param message + * @return The decoded byte array data. + */ + public static byte[] decodeFromBase64(String message) { + return Base64.decode(message); + } + + /** + * Encode byte array data into a Base64 String for transmission. + * + * @param message + * The message to encode. + * @return The encoded data as a String. + */ + public static String encodeToBase64(byte[] message) { + return Base64.encode(message); + } + + /** + * + * @param data + * @return + */ + public static String marshallData(Object data) + throws CollaborationException { + String marshalledData = null; + if (data != null) { + StringBuilder sb = new StringBuilder(); + byte[] marshalledBinary = null; + SerializationMode mode = SerializationMode.getMode(data); + switch (mode) { + case THRIFT: { + try { + if (COMPRESSION_OFF) { + marshalledBinary = SerializationUtil + .transformToThrift(data); + sb.append(ENV_THRIFT); + } else { + /* + * compress(thrift(data)) + */ + byte[] marshalledThrift = SerializationUtil + .transformToThrift(data); + marshalledBinary = CompressionUtil + .compress(marshalledThrift); + sb.append(ENV_THRIFT_COMPRESSED); + } + } catch (Exception e) { + throw new CollaborationException( + "[THRIFT] Could not serialize object", e); + } + break; + } + case JAXB: { + try { + if (COMPRESSION_OFF) { + String s = SerializationUtil.marshalToXml(data); + if (s != null) { + sb.append(ENV_JAXB); + sb.append(s); + } + } else { + String rawString = SerializationUtil.marshalToXml(data); + marshalledBinary = CompressionUtil.compress(rawString + .getBytes()); + sb.append(ENV_JAXB_COMPRESSED); + } + } catch (Exception je) { + throw new CollaborationException( + "[JAXB] Could not serialize object", je); + } + break; + } + case JAVA: { + break; + } + case STRING: { + sb.append(ENV_STRING); + sb.append(data); + break; + } + case NONE: { + throw new CollaborationException("Serialization of " + + data.getClass().getName() + " not supported"); + } + case ISNULL: { + break; + } + } + if (marshalledBinary != null) { + sb.append(encodeToBase64(marshalledBinary)); + } + if (sb.length() > 0) { + marshalledData = sb.toString(); + } + } + return marshalledData; + } + + /** + * + * @param data + * @return + * @throws CollaborationException + */ + public static Object unMarshallData(String data) + throws CollaborationException { + Object unMarshalledData = null; + if (data != null) { + // look for the envelope header first + if (data.startsWith(ENV_THRIFT)) { + String s = data.substring(ENV_THRIFT.length()); + try { + byte[] b = decodeFromBase64(s); + unMarshalledData = SerializationUtil.transformFromThrift(b); + } catch (SerializationException e) { + throw new CollaborationException( + "Could not deserialize object", e); + } + } else if (data.startsWith(ENV_THRIFT_COMPRESSED)) { + String s = data.substring(ENV_THRIFT_COMPRESSED.length()); + try { + byte[] rawBytes = decodeFromBase64(s); + byte[] uncompressedBytes = CompressionUtil + .uncompress(rawBytes); + + unMarshalledData = SerializationUtil + .transformFromThrift(uncompressedBytes); + // unMarshalledData = SerializationUtil + // .transformFromThrift(createCompressionInputStream(rawBytes)); + } catch (Exception e) { + throw new CollaborationException( + "Could not deserialize object", e); + } + } else if (data.startsWith(ENV_JAXB)) { + String s = data.substring(ENV_JAXB.length()); + try { + unMarshalledData = SerializationUtil.unmarshalFromXml(s); + } catch (JAXBException je) { + throw new CollaborationException( + "[JAXB] Could not deserialize object", je); + } + } else if (data.startsWith(ENV_JAXB_COMPRESSED)) { + String rawString = data.substring(ENV_JAXB_COMPRESSED.length()); + try { + byte[] rawBytes = decodeFromBase64(rawString); + unMarshalledData = SerializationUtil + .unmarshalFromXml(new String(CompressionUtil + .uncompress(rawBytes))); + // unMarshalledData = SerializationUtil + // .unmarshalFromXml(createCompressionInputStream(rawBytes)); + } catch (Exception je) { + throw new CollaborationException( + "[JAXB] Could not deserialize object", je); + } + } else if (data.startsWith(ENV_STRING)) { + unMarshalledData = data.substring(ENV_STRING.length()); + } else if (data.startsWith(ENV_JAVA)) { + throw new CollaborationException("Could not deserialize object"); + } else if (data.startsWith(ENV_NONE)) { + throw new CollaborationException("Could not deserialize object"); + } + } + return unMarshalledData; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/TransferRoleCommand.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/TransferRoleCommand.java new file mode 100644 index 0000000000..e521663359 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/TransferRoleCommand.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * A command to transfer a role to a different user on the session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 5, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +@DynamicSerialize +public class TransferRoleCommand { + + @DynamicSerializeElement + private SharedDisplayRole role; + + @DynamicSerializeElement + private UserId user; + + public SharedDisplayRole getRole() { + return role; + } + + public void setRole(SharedDisplayRole role) { + this.role = role; + } + + public UserId getUser() { + return user; + } + + public void setUser(UserId user) { + this.user = user; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/ChatMessageEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/ChatMessageEvent.java new file mode 100644 index 0000000000..824eff289e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/ChatMessageEvent.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.ITextMessageEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 27, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class ChatMessageEvent implements ITextMessageEvent { + + private final TextMessage message; + + /** + * + * @param msg + */ + public ChatMessageEvent(TextMessage msg) { + message = msg; + } + + /** + * + * @return + * + */ + public TextMessage getMessage() { + return message; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/HttpdCollaborationConfigurationEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/HttpdCollaborationConfigurationEvent.java new file mode 100644 index 0000000000..6ac9220907 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/HttpdCollaborationConfigurationEvent.java @@ -0,0 +1,57 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.IHttpdCollaborationConfigurationEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 11, 2012            bkowal     Initial creation
+ * 
+ * 
+ * + * @author bkowal + * @version 1.0 + */ + +public class HttpdCollaborationConfigurationEvent implements + IHttpdCollaborationConfigurationEvent { + + private final String httpdCollaborationURL; + + /** + * + */ + public HttpdCollaborationConfigurationEvent(String httpdCollaborationURL) { + this.httpdCollaborationURL = httpdCollaborationURL; + } + + @Override + public String getHttpdCollaborationURL() { + return this.httpdCollaborationURL; + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/RosterChangeEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/RosterChangeEvent.java new file mode 100644 index 0000000000..120dd4b24c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/RosterChangeEvent.java @@ -0,0 +1,85 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import org.eclipse.ecf.presence.roster.IRosterItem; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 11, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class RosterChangeEvent implements IRosterChangeEvent { + + private final RosterChangeType type; + + private final IRosterItem item; + + /** + * Create an instance of this event using the given type and entry. + * + * @param type + * The event type. + * @param entry + * The changed entry. + */ + public RosterChangeEvent(RosterChangeType type, IRosterItem item) { + this.type = type; + this.item = item; + } + + /** + * Get the event type. + * + * @return The event type. + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent#getType() + */ + @Override + public RosterChangeType getType() { + return type; + } + + /** + * Get the changed entry + * + * @return The changed entry. + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent#getEntry() + */ + @Override + public IRosterItem getItem() { + return item; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/UserNicknameChangedEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/UserNicknameChangedEvent.java new file mode 100644 index 0000000000..a4bb510747 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/UserNicknameChangedEvent.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import org.eclipse.ecf.core.user.IUser; + +/** + * An event to put on a CollaborationConnection event bus when a users nickname + * has changed to notify all views within this CAVE instance that they need to + * refresh the displays for that user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 25, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class UserNicknameChangedEvent { + + public final IUser user; + + public final String nickname; + + public UserNicknameChangedEvent(IUser user, String nickname) { + this.user = user; + this.nickname = nickname; + } + + public IUser getUser() { + return user; + } + + public String getNickname() { + return nickname; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/UserPresenceChangedEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/UserPresenceChangedEvent.java new file mode 100644 index 0000000000..9758f8ae48 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/UserPresenceChangedEvent.java @@ -0,0 +1,54 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import org.eclipse.ecf.presence.IPresence; + +/** + * Event that is posted when the local uses changes properties of the presence. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 25, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class UserPresenceChangedEvent { + + private final IPresence newPresence; + + public UserPresenceChangedEvent(IPresence newPresence) { + super(); + this.newPresence = newPresence; + } + + public IPresence getNewPresence() { + return newPresence; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/VenueInvitationEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/VenueInvitationEvent.java new file mode 100644 index 0000000000..efbfc9b3c6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/VenueInvitationEvent.java @@ -0,0 +1,98 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 27, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class VenueInvitationEvent implements IVenueInvitationEvent { + + private IQualifiedID venueId; + + private IQualifiedID invitor; + + private String subject; + + private VenueInvite invite; + + /** + * + * @param roomId + * @param invitor + * @param subject + * @param body + */ + public VenueInvitationEvent(IQualifiedID venueId, IQualifiedID invitor, + String subject, VenueInvite invite) { + this.venueId = venueId; + this.invitor = invitor; + this.subject = subject; + this.invite = invite; + } + + /** + * Get the room identifier + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent#getRoomId() + */ + @Override + public IQualifiedID getRoomId() { + return venueId; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent#getInviter() + */ + @Override + public IQualifiedID getInviter() { + return invitor; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent#getSubject() + */ + @Override + public String getSubject() { + return subject; + } + + public VenueInvite getInvite() { + return invite; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/VenueParticipantEvent.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/VenueParticipantEvent.java new file mode 100644 index 0000000000..6691707528 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/event/VenueParticipantEvent.java @@ -0,0 +1,90 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.event; + +import org.eclipse.ecf.presence.IPresence; + +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 20, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class VenueParticipantEvent implements IVenueParticipantEvent { + + private final ParticipantEventType eventType; + + private final UserId participant; + + private IPresence presence; + + public VenueParticipantEvent(UserId participant, + ParticipantEventType eventType) { + this.participant = participant; + this.eventType = eventType; + } + + public VenueParticipantEvent(UserId participant, IPresence presence, + ParticipantEventType eventType) { + this.participant = participant; + this.eventType = eventType; + this.presence = presence; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent#getEventType() + */ + @Override + public ParticipantEventType getEventType() { + return eventType; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent#getParticipant() + */ + @Override + public UserId getParticipant() { + return participant; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent#getPresence() + */ + @Override + public IPresence getPresence() { + return presence; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java new file mode 100644 index 0000000000..cf624f06cb --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/Venue.java @@ -0,0 +1,99 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.info; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.ecf.presence.Presence; +import org.eclipse.ecf.presence.chatroom.IChatRoomContainer; +import org.eclipse.ecf.presence.chatroom.IChatRoomInfo; + +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class Venue implements IVenue { + + private final IChatRoomContainer container; + + private final IVenueInfo info; + + private Map presenceMap = new HashMap();; + + public Venue(IChatRoomContainer container, IChatRoomInfo info) { + this.container = container; + this.info = new VenueInfo(info); + } + + @Override + public IVenueInfo getInfo() { + return info; + } + + @Override + public Collection getParticipants() { + Set participants = new HashSet(); + ID[] ids = container.getChatRoomParticipants(); + for (ID id : ids) { + participants.add(IDConverter.convertFrom(id)); + } + return participants; + } + + @Override + public IPresence getPresence(IUser user) { + IPresence presence = presenceMap.get(user.getID().getName()); + if (presence == null) { + presence = new Presence(Type.UNAVAILABLE); + } + return presence; + } + + public void handlePresenceUpdated(ID fromID, IPresence presence) { + presenceMap.put(fromID.getName(), presence); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/VenueInfo.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/VenueInfo.java new file mode 100644 index 0000000000..c227a803a0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/info/VenueInfo.java @@ -0,0 +1,104 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.info; + +import org.eclipse.ecf.presence.chatroom.IChatRoomInfo; + +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; + +/** + * + * Wrap a chatroom info in a VenueInfo + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 24, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class VenueInfo implements IVenueInfo { + + private IChatRoomInfo info; + + public VenueInfo(IChatRoomInfo info) { + this.info = info; + } + + @Override + public String getVenueDescription() { + return info.getDescription(); + } + + @Override + public String getVenueName() { + return info.getName(); + } + + @Override + public String getVenueSubject() { + return info.getSubject(); + } + + @Override + public String getVenueID() { + return info.getRoomID().toExternalForm(); + } + + @Override + public int getParticipantCount() { + return info.getParticipantsCount(); + } + + @Override + public boolean isModerated() { + return info.isModerated(); + } + + @Override + public boolean isPersistent() { + return info.isPersistent(); + } + + @Override + public boolean requiresPassword() { + return info.requiresPassword(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(String.format("[%s]:", getVenueName())); + sb.append(String.format("[%s]:", getVenueID())); + sb.append(String.format("mod[%s]:", (isModerated()) ? "T" : "F")); + sb.append(String.format("pers[%s]:", (isPersistent()) ? "T" : "F")); + sb.append(String.format("pass[%s]:", (requiresPassword()) ? "T" : "F")); + sb.append(String.format("\n subject : %s", getVenueSubject())); + sb.append(String.format("\n description : %s", getVenueDescription())); + + return sb.toString(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/AccountManager.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/AccountManager.java new file mode 100644 index 0000000000..1f75bd7987 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/AccountManager.java @@ -0,0 +1,310 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.Arrays; +import java.util.Map; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresenceContainerAdapter; +import org.eclipse.ecf.presence.IPresenceSender; +import org.eclipse.ecf.presence.Presence; +import org.eclipse.ecf.presence.roster.IRosterManager; +import org.eclipse.ecf.presence.roster.IRosterSubscriptionListener; + +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.roster.ISubscriptionResponder; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.provider.event.UserPresenceChangedEvent; + +/** + * TODO Add Description + * + *
    + * EventBus subscription events. + *
  • ISubscriptionResponseEvent : This event is posted when a subscription + * request has been responded to.
  • + *
+ * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class AccountManager implements IAccountManager { + + private IRosterSubscriptionListener autoResponder = new IRosterSubscriptionListener() { + + @Override + public void handleSubscribeRequest(ID fromID) { + + IQualifiedID fromId = null; + + IPresence.Type subscribedType = IPresence.Type.UNKNOWN; + if (responder != null) { + subscribedType = responder.handleSubscribeRequest(fromId); + } else { + subscribedType = IPresence.Type.SUBSCRIBED; + } + + IPresence presence = new Presence(subscribedType, null, + IPresence.Mode.AVAILABLE); + try { + sendPresence(fromID, presence); + } catch (CollaborationException e) { + e.printStackTrace(); + } + } + + @Override + public void handleSubscribed(ID fromID) { + System.out.println("AccountManager.handleSubscribed " + fromID); + } + + @Override + public void handleUnsubscribed(ID fromID) { + System.out.println("AccountManager.handleUnSubscribed " + fromID); + } + }; + + private boolean autoRespond = true; + + private IPresenceContainerAdapter presenceAdapter; + + private ISubscriptionResponder responder; + + private CollaborationConnection sessionManager = null; + + /** + * + * @param adapter + */ + AccountManager(IPresenceContainerAdapter adapter, + CollaborationConnection manager) { + sessionManager = manager; + presenceAdapter = adapter; + presenceAdapter.getRosterManager().addRosterSubscriptionListener( + autoResponder); + } + + /** + * Set the auto subscription mode to ON or OFF. If set to off then any + * currently assigned autoresponder is set to null. + * + * @param mode + * The auto subscription mode. + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#setAutoSubscriptionMode(boolean) + */ + @Override + public void setAutoSubscriptionMode(boolean auto) { + autoRespond = auto; + if (!auto) { + responder = null; + } + } + + /** + * + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#getAutoSubscriptionMode() + */ + @Override + public boolean getAutoSubscriptionMode() { + return autoRespond; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#setSubscriptionRequestResponder(com.raytheon.uf.viz.collaboration.comm.identity.roster.ISubscriptionResponder) + */ + @Override + public void setSubscriptionRequestResponder(ISubscriptionResponder responder) { + this.responder = responder; + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#removeSubscriptionRequestResponder() + */ + @Override + public void removeSubscriptionRequestResponder() { + responder = null; + } + + /** + * + * @param password + * The new password. For security the password is a character + * array that will be zero'd after use. + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#changePassword(char[]) + */ + @Override + public void changePassword(char[] password) throws CollaborationException { + org.eclipse.ecf.presence.IAccountManager manager = presenceAdapter + .getAccountManager(); + if (manager != null) { + try { + manager.changePassword(new String(password)); + // all done so clear the password. + Arrays.fill(password, (char) 0); + } catch (ECFException e) { + throw new CollaborationException( + "Could not change account password"); + } + } + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#deleteAccount() + */ + @Override + public void deleteAccount() throws CollaborationException { + org.eclipse.ecf.presence.IAccountManager manager = presenceAdapter + .getAccountManager(); + if (manager != null) { + try { + manager.deleteAccount(); + } catch (ECFException e) { + throw new CollaborationException("Could not delete account"); + } + } + } + + /** + * Determines if the server allows new accounts to be created by the user. + * + * @throws CollaborationException + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#canCreateAccount() + */ + @Override + public boolean canCreateAccount() throws CollaborationException { + boolean canCreate = false; + org.eclipse.ecf.presence.IAccountManager manager = presenceAdapter + .getAccountManager(); + if (manager != null) { + try { + canCreate = manager.isAccountCreationSupported(); + } catch (ECFException e) { + throw new CollaborationException( + "Error attempting to determine if accounts may be created."); + } + } + return canCreate; + } + + /** + * TODO : Body of method + * + * @param password + * @param attributes + * @see com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager#createAccount(java.lang.String, + * char[], java.util.Map) + */ + @SuppressWarnings("rawtypes") + @Override + public void createAccount(String name, char[] password, + Map attributes) throws CollaborationException { + if (name != null) { + if (password != null) { + // create the account + org.eclipse.ecf.presence.IAccountManager manager = presenceAdapter + .getAccountManager(); + if (manager != null) { + Map map = null; + if (attributes != null) { + map = (Map) attributes; + } + + try { + manager.createAccount(name, new String(password), map); + } catch (ECFException e) { + throw new CollaborationException( + "Could not create account "); + } + } + // all done so clear the password. + Arrays.fill(password, (char) 0); + } + } + } + + /** + * + * + * @param userPresence + * @throws CollaborationException + */ + @Override + public void sendPresence(IPresence userPresence) + throws CollaborationException { + + IRosterManager manager = presenceAdapter.getRosterManager(); + IPresenceSender sender = manager.getPresenceSender(); + + try { + sender.sendPresenceUpdate(null, userPresence); + sessionManager.setPresence(userPresence); + for (ISession session : sessionManager.getSessions()) { + if (session instanceof IVenueSession) { + ((IVenueSession) session).sendPresence(userPresence); + } + } + sessionManager + .postEvent(new UserPresenceChangedEvent(userPresence)); + } catch (ECFException e) { + throw new CollaborationException("Could not send presence"); + } + } + + /** + * + * + * @param userPresence + * @throws CollaborationException + */ + public void sendPresence(ID toId, IPresence userPresence) + throws CollaborationException { + + IRosterManager manager = presenceAdapter.getRosterManager(); + IPresenceSender sender = manager.getPresenceSender(); + + try { + sender.sendPresenceUpdate(toId, userPresence); + sessionManager.setPresence(userPresence); + } catch (ECFException e) { + throw new CollaborationException("Could not send presence"); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/BaseSession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/BaseSession.java new file mode 100644 index 0000000000..c16eb830ff --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/BaseSession.java @@ -0,0 +1,272 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.IPresenceContainerAdapter; + +import com.google.common.eventbus.EventBus; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ +public abstract class BaseSession implements ISession { + + protected final String sessionId; + + private EventBus managerEventBus; + + private EventBus eventBus; + + private Map eventSubscribers; + + private IContainer connectionContainer; + + private IPresenceContainerAdapter connectionPresence = null; + + private Namespace connectionNamespace = null; + + private CollaborationConnection connection; + + /** + * + * @param container + * @param externalBus + * @param manager + */ + protected BaseSession(IContainer container, EventBus externalBus, + CollaborationConnection manager) throws CollaborationException { + this(container, externalBus, manager, UUID.randomUUID().toString()); + } + + /** + * + * @param container + * @param externalBus + * @param manager + * @param sessionId + */ + protected BaseSession(IContainer container, EventBus externalBus, + CollaborationConnection manager, String sessionId) + throws CollaborationException { + // Set the session identifier. + this.sessionId = sessionId; + managerEventBus = externalBus; + eventBus = new EventBus(); + connectionContainer = container; + connection = manager; + eventSubscribers = new HashMap(); + setup(); + } + + /** + * + * @throws ECFException + */ + void setup() { + // Check if the container has been set up previously. + if (connectionContainer != null) { + connectionNamespace = connectionContainer.getConnectNamespace(); + connectionPresence = (IPresenceContainerAdapter) connectionContainer + .getAdapter(IPresenceContainerAdapter.class); + } + } + + /** + * Get access to the peer to peer session instance. + * + * @return The peer to peer chat session instance. + * @throws CollaborationException + */ + PeerToPeerChat getP2PSession() throws CollaborationException { + return (PeerToPeerChat) connection.getPeerToPeerSession(); + } + + /** + * + * @return + */ + IContainer getConnectionContainer() { + return connectionContainer; + } + + /** + * + * @return + */ + Namespace getConnectionNamespace() { + return connectionNamespace; + } + + /** + * + * @return + */ + IPresenceContainerAdapter getConnectionPresenceAdapter() { + return connectionPresence; + } + + /** + * + * @return + */ + EventBus getManagerEventPublisher() { + return managerEventBus; + } + + /** + * + * @return + */ + CollaborationConnection getSessionManager() { + return connection; + } + + /** + * + * @param name + * @return + */ + public ID createID(String name) throws IDCreateException { + ID id = null; + if (connectionNamespace != null) { + id = IDFactory.getDefault().createID(connectionNamespace, name); + } + return id; + } + + // ***************** + // Implement IEventPublisher methods + // ***************** + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISession#getUserID() + */ + @Override + public UserId getUserID() { + return connection.getUser(); + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISession#isConnected() + */ + @Override + public boolean isConnected() { + boolean connected = false; + if (connectionContainer != null) { + connected = (connectionContainer.getConnectedID() != null); + } + return connected; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISession#close() + */ + @Override + public void close() { + + // Unregister any handlers added using this session + // for(Object o : eventSubscribers.values()) { + // managerEventBus.unregister(o); + // } + connection.removeSession(this); + } + + /** + * Get the session identifier. + * + * @return The session id for this session. + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISession#getSessionId() + */ + @Override + public String getSessionId() { + return sessionId; + } + + // ***************** + // Implement IEventPublisher methods + // ***************** + + /** + * + * @param handler + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher#registerEventHandler(java.lang.Object) + */ + @Override + public void registerEventHandler(Object handler) { + if (!eventSubscribers.containsKey(handler)) { + eventBus.register(handler); + eventSubscribers.put(handler, handler); + } + } + + /** + * + * @param handler + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher#unregisterEventHandler(java.lang.Object) + */ + @Override + public void unregisterEventHandler(Object handler) { + eventSubscribers.remove(handler); + eventBus.unregister(handler); + } + + /** + * + */ + @Override + public void postEvent(Object event) { + if (event != null) { + eventBus.post(event); + } + } + + @Override + public CollaborationConnection getConnection() { + return connection; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/CollaborationConnection.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/CollaborationConnection.java new file mode 100644 index 0000000000..6d81fb6a42 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/CollaborationConnection.java @@ -0,0 +1,736 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.ContainerFactory; +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDCreateException; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.identity.Namespace; +import org.eclipse.ecf.core.security.ConnectContextFactory; +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Mode; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.ecf.presence.IPresenceContainerAdapter; +import org.eclipse.ecf.presence.IPresenceListener; +import org.eclipse.ecf.presence.Presence; +import org.eclipse.ecf.presence.chatroom.IChatRoomInfo; +import org.eclipse.ecf.presence.chatroom.IChatRoomInvitationListener; +import org.eclipse.ecf.presence.chatroom.IChatRoomManager; +import org.eclipse.ecf.presence.roster.IRoster; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterItem; +import org.eclipse.ecf.presence.roster.IRosterListener; +import org.eclipse.ecf.presence.roster.IRosterManager; +import org.eclipse.ecf.provider.xmpp.identity.XMPPRoomID; + +import com.google.common.eventbus.EventBus; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.IAccountManager; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.MultipleLoginException; +import com.raytheon.uf.viz.collaboration.comm.identity.UsernamePasswordException; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.SharedDisplayVenueInvite; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; +import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueInvitationEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.info.VenueInfo; +import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId; + +/** + * + *
    + *
  • EventBus subscription events.
  • + *
      + *
    • IVenueInvitationEvent : This event is posted when the + * SessionManager receives a venue invitation requesting that the user join some + * particular collaboration session.
    • + *
    • IConnectionStatusEvent : This event is posted when the + * state of the underlying connection changes, reconnecting, connecting, + * disconnected, for example.
    • + *
    • IRosterChangeEvent : This event is posted when roster + * changes have occurred.
    • + *
    • --------------- : ---------------.
    • + *
    + *
+ * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * Apr 18, 2012            njensen      Major cleanup
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent + */ + +public class CollaborationConnection implements IEventPublisher { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CollaborationConnection.class); + + private static final String PROVIDER = "com.raytheon.uf.viz.collaboration.comm.xmpp";// "ecf.xmpp.smack"; + + private static CollaborationConnection instance = null; + + private static Map instanceMap = new HashMap(); + + private Map sessions; + + private UserId account; + + private String password; + + private UserId user; + + private IPresence userPresence; + + private IChatRoomInvitationListener intInvitationListener; + + private IPresenceContainerAdapter presenceAdapter; + + private Namespace connectionNamespace = null; + + private PeerToPeerChat chatInstance = null; + + private IAccountManager accountManager = null; + + private IRosterManager rosterManager = null; + + private IContainer container = null; + + private EventBus eventBus; + + private ContactsManager contactsMgr; + + private CollaborationConnectionData connectionData; + + private CollaborationConnection(CollaborationConnectionData connectionData) + throws CollaborationException { + this.connectionData = connectionData; + UserId account = new UserId(connectionData.getUserName(), + connectionData.getServer()); + String password = connectionData.getPassword(); + IPresence initialPresence = new Presence(Type.AVAILABLE, + connectionData.getMessage(), Mode.fromString(connectionData + .getStatus().toLowerCase()), + connectionData.getAttributes()); + + eventBus = new EventBus(); + sessions = new HashMap(); + + try { + container = ContainerFactory.getDefault().createContainer(PROVIDER); + + if (container != null) { + // add the listeners before we connect so we don't potentially + // miss something + presenceAdapter = Tools.getPresenceContainerAdapter(container, + IPresenceContainerAdapter.class); + this.setupInternalConnectionListeners(); + } + + } catch (ContainerCreateException cce) { + closeInternals(); + throw new CollaborationException(String.format( + "Could not create container for provider [%s]", PROVIDER)); + } + this.account = account; + this.password = password; + try { + connectToContainer(); + } catch (ContainerConnectException e) { + closeInternals(); + // ECF does a very good job of wrapping up login exceptions so it is + // hard to tell why the login failed. This code will attempt to + // analyze the cause of the failure and in some circumstances + // produce a helpful error. Since this is relying on string + // comparison of exception messages it is very likely that if the + // ECF provider is changed or updated that this will stop producing + // helpful messages. Unfortunately ECF does not provide any other + // mechanism for figuring out why login failed. + for (Throwable t = e; t != null && t != t.getCause(); t = t + .getCause()) { + if (t.getMessage().contains("authentication failed")) { + throw new UsernamePasswordException( + "Login failed. Invalid username or password", e); + } else if (t.getMessage().equals("conflict(409)")) { + throw new MultipleLoginException( + "Login failed. User already logged in elsewhere", + e); + } + } + // In cases where we can't produce anything helpful, at least let + // the user know that it failed and hopeful something in the stack + // trace will be useful in the DR. + throw new CollaborationException("Login failed.", e); + + } + ID id = container.getConnectedID(); + if (id != null) { + String name = Tools.parseName(id.getName()); + String host = Tools.parseHost(id.getName()); + String resource = Tools.parseResource(id.getName()); + user = new UserId(name, host, resource); + user.setId(id); + } + + setupAccountManager(); + + setupInternalVenueInvitationListener(); + setupP2PComm(presenceAdapter); + getPeerToPeerSession(); + + userPresence = initialPresence; + if (accountManager != null && initialPresence != null) { + accountManager.sendPresence(initialPresence); + } + + contactsMgr = new ContactsManager(this); + this.registerEventHandler(contactsMgr); + + instanceMap.put(connectionData, this); + if (instance == null) { + instance = this; + } + } + + public CollaborationConnectionData getConnectionData() { + return connectionData; + } + + /** + * @return + * @see com.raytheon.uf.viz.collaboration.comm.identity.roster.IRoster#getUser() + */ + public UserId getUser() { + return user; + } + + /** + * + * @return + */ + public IPresence getPresence() { + return userPresence; + } + + /** + * + * @return + */ + public void setPresence(IPresence presence) { + userPresence = presence; + } + + /** + * @throws CollaborationException + * @throws ContainerConnectException + * + */ + private void connectToContainer() throws CollaborationException, + ContainerConnectException { + if (container.getConnectedID() == null) { + connectionNamespace = container.getConnectNamespace(); + + // Now connect + ID targetID = createID(account); + presenceAdapter = Tools.getPresenceContainerAdapter(container, + IPresenceContainerAdapter.class); + container.connect(targetID, ConnectContextFactory + .createPasswordConnectContext(password)); + } + } + + /** + * + */ + private void setupAccountManager() { + if (accountManager == null) { + if (isConnected() && (presenceAdapter != null)) { + accountManager = new AccountManager(presenceAdapter, this); + } + } + } + + /** + * Get the account manager for this connection. + * + * @return The account manager for this connection. + */ + public IAccountManager getAccountManager() { + if (accountManager == null) { + setupAccountManager(); + } + return accountManager; + } + + /** + * + */ + private void setupRosterManager() { + rosterManager = presenceAdapter.getRosterManager(); + } + + /** + * + * @return + */ + public IPresenceContainerAdapter getPresenceContainerAdapter() { + return presenceAdapter; + } + + /** + * + * @return + */ + public IRosterManager getRosterManager() { + if (rosterManager == null) { + setupRosterManager(); + } + return rosterManager; + } + + /** + * Is this SessionManager currently connected? + * + * @return Is this SessionManager currently connected? + */ + public boolean isConnected() { + return ((container != null) && (container.getConnectedID() != null)); + } + + private void closeInternals() { + if (container != null) { + + chatInstance = null; + // Get rid of the account and roster managers + container.disconnect(); + container.dispose(); + container = null; + } + instanceMap.remove(connectionData); + if (this == instance) { + instance = null; + } + } + + /** + * + */ + public void close() { + if (container != null) { + // Close any created sessions. + Collection toRemove = sessions.values(); + sessions.clear(); + for (ISession session : toRemove) { + if ((chatInstance != null) && chatInstance.equals(session)) { + chatInstance.close(); + chatInstance = null; + } else { + session.close(); + } + } + chatInstance = null; + } + closeInternals(); + } + + /** + * Get the PeerToPeerChat session instance. + * + * @return + */ + public ISession getPeerToPeerSession() throws CollaborationException { + if (chatInstance == null) { + chatInstance = new PeerToPeerChat(container, eventBus, this); + sessions.put(chatInstance.getSessionId(), chatInstance); + postEvent(chatInstance); + } + return chatInstance; + } + + public ISharedDisplaySession joinCollaborationVenue( + IVenueInvitationEvent invitation) throws CollaborationException { + SharedDisplaySession session = null; + String venueName = invitation.getRoomId().getName(); + String sessionId = invitation.getInvite().getSessionId(); + session = new SharedDisplaySession(container, eventBus, this, sessionId); + if (session != null) { + session.joinVenue(venueName); + + if (invitation.getInvite() instanceof SharedDisplayVenueInvite) { + SharedDisplayVenueInvite invite = (SharedDisplayVenueInvite) invitation + .getInvite(); + session.setCurrentDataProvider(invite.getDataProvider()); + session.setCurrentSessionLeader(invite.getSessionLeader()); + } + + sessions.put(session.getSessionId(), session); + postEvent(session); + } + return session; + } + + /** + * + * @param venueName + * @return + * @throws CollaborationException + */ + public ISharedDisplaySession createCollaborationVenue(String venueName, + String subject) throws CollaborationException { + SharedDisplaySession session = null; + try { + session = new SharedDisplaySession(container, eventBus, this); + + session.createVenue(venueName, subject); + session.setCurrentSessionLeader(user); + session.setCurrentDataProvider(user); + + sessions.put(session.getSessionId(), session); + postEvent(session); + return session; + } catch (Exception e) { + throw new CollaborationException( + "Error creating collaboration venue " + venueName, e); + } + } + + /** + * + * @param venueName + * @return + * @throws CollaborationException + */ + public IVenueSession joinTextOnlyVenue(String venueName) + throws CollaborationException { + VenueSession session = null; + try { + session = new VenueSession(container, eventBus, this); + if (session != null) { + session.joinVenue(venueName); + sessions.put(session.getSessionId(), session); + postEvent(session); + } + } catch (Exception e) { + throw new CollaborationException( + "Error joining venue " + venueName, e); + } + return session; + } + + /** + * + * @param venueName + * @return + * @throws CollaborationException + */ + public IVenueSession createTextOnlyVenue(String venueName, String subject) + throws CollaborationException { + VenueSession session = null; + try { + session = new VenueSession(container, eventBus, this); + if (session != null) { + session.createVenue(venueName, subject); + sessions.put(session.getSessionId(), session); + postEvent(session); + } + } catch (Exception e) { + throw new CollaborationException("Error creating venue " + + venueName, e); + } + return session; + } + + /** + * + * @param session + */ + protected void removeSession(ISession session) { + sessions.remove(session.getSessionId()); + postEvent(session); + } + + /** + * + * @return + */ + public Collection getVenueInfo() { + // Check to see if the container has been connected. + Collection info = new ArrayList(); + if (isConnected()) { + IPresenceContainerAdapter presenceAdapter = Tools + .getPresenceContainerAdapter(container, + IPresenceContainerAdapter.class); + IChatRoomManager venueManager = presenceAdapter + .getChatRoomManager(); + if (venueManager != null) { + IChatRoomInfo[] roomInfo = venueManager.getChatRoomInfos(); + for (IChatRoomInfo rInfo : roomInfo) { + IVenueInfo vi = new VenueInfo(rInfo); + info.add(vi); + } + } + } + + return info; + } + + // *************************** + // Connection listener + // *************************** + + /** + * + */ + private void setupInternalConnectionListeners() { + + presenceAdapter.getRosterManager().addPresenceListener( + new IPresenceListener() { + + @Override + public void handlePresence(ID fromId, + org.eclipse.ecf.presence.IPresence presence) { + + if (rosterManager != null) { + if (contactsMgr != null) { + IUser u = contactsMgr.getUser(fromId); + if (u != null) { + IRosterEntry entry = contactsMgr + .getRosterEntry(u); + eventBus.post(entry); + } + } + } + } + }); + + presenceAdapter.getRosterManager().addRosterListener( + new IRosterListener() { + + @Override + public void handleRosterEntryAdd(IRosterEntry entry) { + IRosterChangeEvent event = new RosterChangeEvent( + RosterChangeType.ADD, entry); + eventBus.post(event); + } + + @Override + public void handleRosterUpdate(IRoster roster, + IRosterItem item) { + IRosterChangeEvent event = new RosterChangeEvent( + RosterChangeType.MODIFY, item); + eventBus.post(event); + } + + @Override + public void handleRosterEntryRemove(IRosterEntry entry) { + IRosterChangeEvent event = new RosterChangeEvent( + RosterChangeType.DELETE, entry); + eventBus.post(event); + } + }); + } + + public ISession getSession(String sessionId) { + return sessions.get(sessionId); + } + + private void setupP2PComm(IPresenceContainerAdapter presenceAdapter) { + if (isConnected() && (presenceAdapter != null)) { + PeerToPeerCommHelper helper = new PeerToPeerCommHelper(this); + presenceAdapter.getChatManager().addMessageListener(helper); + } + } + + // *************************** + // Venue invitation listener management + // *************************** + + /** + * + */ + private void setupInternalVenueInvitationListener() { + if (isConnected() && (presenceAdapter != null)) { + IChatRoomManager venueManager = presenceAdapter + .getChatRoomManager(); + if (venueManager != null) { + intInvitationListener = new IChatRoomInvitationListener() { + @Override + public void handleInvitationReceived(ID roomID, ID from, + String subject, String body) { + + IQualifiedID venueId = null; + if (roomID instanceof XMPPRoomID) { + XMPPRoomID room = (XMPPRoomID) roomID; + venueId = new VenueId(); + venueId.setName(room.getLongName()); + + } + if (venueId != null) { + IQualifiedID id = IDConverter.convertFrom(from); + + UserId invitor = new UserId(id.getName(), + id.getHost(), id.getResource()); + + VenueInvite received; + try { + received = (VenueInvite) Tools + .unMarshallData(body); + + if (subject == null) { + subject = received.getSubject(); + if (subject == null) { + subject = presenceAdapter + .getChatRoomManager() + .getChatRoomInfo( + roomID.getName()) + .getSubject(); + } + } + + IVenueInvitationEvent invite = new VenueInvitationEvent( + venueId, invitor, subject, received); + eventBus.post(invite); + } catch (CollaborationException e) { + statusHandler + .handle(Priority.PROBLEM, + "Error handling received invite message", + e); + } + + } + } + }; + venueManager.addInvitationListener(intInvitationListener); + } + } + } + + /** + * Register an event handler with this + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher#registerEventHandler(java.lang.Object) + */ + @Override + public void registerEventHandler(Object handler) { + eventBus.register(handler); + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IEventPublisher#unregisterEventHandler(java.lang.Object) + */ + @Override + public void unregisterEventHandler(Object handler) { + eventBus.unregister(handler); + } + + @Override + public void postEvent(Object event) { + if (event != null) { + eventBus.post(event); + } + } + + public ContactsManager getContactsManager() { + return contactsMgr; + } + + /** + * + * @param name + * @return + */ + public ID createID(UserId name) throws CollaborationException { + ID id = null; + try { + if (connectionNamespace != null) { + id = IDFactory.getDefault().createID(connectionNamespace, + name.getFQName()); + } + } catch (IDCreateException idce) { + throw new CollaborationException("Could not create id"); + } + return id; + } + + public Collection getSessions() { + return sessions.values(); + } + + /** + * Returns the currently connected connection or null if it's not connected + * + * @return + */ + public static CollaborationConnection getConnection() { + return instance; + } + + /** + * Create a {@link CollaborationConnection} given the + * {@link CollaborationConnectionData} + * + * @param userData + * @return + * @throws CollaborationException + */ + public static CollaborationConnection connect( + CollaborationConnectionData userData) throws CollaborationException { + if (instance != null) { + throw new CollaborationException("Already connected"); + } else { + instance = new CollaborationConnection(userData); + return getConnection(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/CollaborationConnectionData.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/CollaborationConnectionData.java new file mode 100644 index 0000000000..0c635c23e3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/CollaborationConnectionData.java @@ -0,0 +1,218 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.HashMap; +import java.util.Map; + +/** + * Collaboration connection data object used for creating a {@link CollaborationConnection} + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationConnectionData { + + private String server; + + private String userName; + + private String password; + + private String status; + + private String message; + + private Map attributes; + + public CollaborationConnectionData() { + attributes = new HashMap(); + } + + /** + * @return the server + */ + public String getServer() { + return server; + } + + /** + * @param server + * the server to set + */ + public void setServer(String server) { + this.server = server; + } + + /** + * @return the userName + */ + public String getUserName() { + return userName; + } + + /** + * @param userName + * the userName to set + */ + public void setUserName(String userName) { + this.userName = userName; + } + + /** + * @return the password + */ + public String getPassword() { + return password; + } + + /** + * @param password + * the password to set + */ + public void setPassword(String password) { + this.password = password; + } + + /** + * @return the status + */ + public String getStatus() { + return status; + } + + /** + * @param status + * the status to set + */ + public void setStatus(String status) { + this.status = status; + } + + /** + * @return the message + */ + public String getMessage() { + return message; + } + + /** + * @param message + * the message to set + */ + public void setMessage(String message) { + this.message = message; + } + + /** + * @return the attributes + */ + public Map getAttributes() { + return new HashMap(attributes); + } + + /** + * @param attributes + * the attributes to set + */ + public void setAttributes(Map attributes) { + this.attributes = new HashMap(attributes); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((attributes == null) ? 0 : attributes.hashCode()); + result = prime * result + ((message == null) ? 0 : message.hashCode()); + result = prime * result + + ((password == null) ? 0 : password.hashCode()); + result = prime * result + ((server == null) ? 0 : server.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + + ((userName == null) ? 0 : userName.hashCode()); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CollaborationConnectionData other = (CollaborationConnectionData) obj; + if (attributes == null) { + if (other.attributes != null) + return false; + } else if (!attributes.equals(other.attributes)) + return false; + if (message == null) { + if (other.message != null) + return false; + } else if (!message.equals(other.message)) + return false; + if (password == null) { + if (other.password != null) + return false; + } else if (!password.equals(other.password)) + return false; + if (server == null) { + if (other.server != null) + return false; + } else if (!server.equals(other.server)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + if (userName == null) { + if (other.userName != null) + return false; + } else if (!userName.equals(other.userName)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/PeerToPeerChat.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/PeerToPeerChat.java new file mode 100644 index 0000000000..b7fec62a7f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/PeerToPeerChat.java @@ -0,0 +1,128 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.im.IChatMessage; +import org.eclipse.ecf.presence.im.IChatMessageSender; + +import com.google.common.eventbus.EventBus; +import com.raytheon.uf.viz.collaboration.comm.Activator; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; +import com.raytheon.uf.viz.collaboration.comm.identity.IPeerToPeer; +import com.raytheon.uf.viz.collaboration.comm.identity.IPropertied.Property; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; + +/** + * + * + * Only one instance of this class should be created. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            jkorman     Initial creation
+ * Apr 18, 2012            njensen      Cleanup
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class PeerToPeerChat extends BaseSession implements IPeerToPeer { + + private IChatMessageSender chatSender = null; + + /** + * + * @param container + * @param externalBus + * @param manager + */ + PeerToPeerChat(IContainer container, EventBus externalBus, + CollaborationConnection manager) throws CollaborationException { + super(container, externalBus, manager); + chatSender = getConnectionPresenceAdapter().getChatManager() + .getChatMessageSender(); + } + + /** + * @throws CollaborationException + * + */ + @Override + public void sendPeerToPeer(IMessage message) throws CollaborationException { + if (chatSender != null) { + ID toID = createID(message.getTo().getFQName()); + String subject = message.getSubject(); + String body = message.getBody(); + Collection properties = message.getProperties(); + Map props = null; + if ((properties != null) && (properties.size() > 0)) { + props = new HashMap(); + for (Property p : properties) { + props.put(p.getKey(), p.getValue()); + } + } + try { + Activator + .getDefault() + .getNetworkStats() + .log(Activator.PEER_TO_PEER, + message.getBody().length(), 0); + chatSender.sendChatMessage(toID, null, IChatMessage.Type.CHAT, + subject, body, props); + } catch (ECFException e) { + throw new CollaborationException( + "Error sending message to peer " + + message.getTo().getName(), e); + } + } + } + + /** + * Send a message to the named recipient. + * + * @param to + * The recipient of the message. + * @param message + * The body of the message to send. + * @throws CollaborationException + */ + @Override + public void sendPeerToPeer(IQualifiedID to, String message) + throws CollaborationException { + TextMessage msg = new TextMessage(to, message); + this.sendPeerToPeer(msg); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/PeerToPeerCommHelper.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/PeerToPeerCommHelper.java new file mode 100644 index 0000000000..fbded13749 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/PeerToPeerCommHelper.java @@ -0,0 +1,259 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.Map; + +import org.eclipse.ecf.presence.IIMMessageEvent; +import org.eclipse.ecf.presence.IIMMessageListener; +import org.eclipse.ecf.presence.im.IChatMessage; +import org.eclipse.ecf.presence.im.IChatMessageEvent; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.Activator; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IHttpdCollaborationConfigurationEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IHttpdXmppMessage; +import com.raytheon.uf.viz.collaboration.comm.identity.event.ITextMessageEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; +import com.raytheon.uf.viz.collaboration.comm.provider.event.ChatMessageEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.event.HttpdCollaborationConfigurationEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; + +/** + * Listens for peer to peer messages and routes them appropriately. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 28, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class PeerToPeerCommHelper implements IIMMessageListener { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(PeerToPeerCommHelper.class); + + private static Object httpServerLockObj = new Object(); + + private static String httpServer; + + public static String getCollaborationHttpServer() { + /** + * Wait for initialization of field httpServer. + */ + synchronized (httpServerLockObj) { + try { + while (httpServer == null) { + httpServerLockObj.wait(500); + } + } catch (InterruptedException e) { + statusHandler.handle(Priority.PROBLEM, + "PeerToPeerCommHelper unable to resolve server URL. " + + e.getLocalizedMessage(), e); + } + } + return httpServer; + } + + private CollaborationConnection manager; + + /** + * + * @param manager + * @param presenceAdapter + */ + protected PeerToPeerCommHelper(CollaborationConnection manager) { + this.manager = manager; + } + + /** + * + */ + @Override + public void handleMessageEvent(IIMMessageEvent messageEvent) { + if (messageEvent instanceof IChatMessageEvent) { + IChatMessageEvent event = (IChatMessageEvent) messageEvent; + + IChatMessage msg = event.getChatMessage(); + String body = msg.getBody(); + Activator.getDefault().getNetworkStats() + .log(Activator.PEER_TO_PEER, 0, body.length()); + if (body != null) { + if (body.startsWith(Tools.CMD_PREAMBLE)) { + routeData(msg); + } else if (body.startsWith(Tools.CONFIG_PREAMBLE)) { + this.handleConfiguration(body); + } else { + // anything else pass to the normal text + routeMessage(msg); + } + } + } + } + + /** + * + * @param message + */ + private void routeData(IChatMessage message) { + Object object = null; + try { + object = Tools.unMarshallData(message.getBody()); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error unmarshalling PeerToPeer data", e); + } + if (object != null) { + String sessionId = (String) message.getProperties().get( + Tools.PROP_SESSION_ID); + if (sessionId == null) { + manager.postEvent(object); + } else { + // Ok, we have a session id. + ISession session = manager.getSession(sessionId); + if (session != null) { + session.postEvent(object); + } else { + statusHandler.handle(Priority.PROBLEM, + "ERROR: Unknown sessionid [" + sessionId + "]"); + } + } + } + } + + /** + * + * @param message + */ + private void routeMessage(IChatMessage message) { + IQualifiedID fromId = IDConverter.convertFrom(message.getFromID()); + fromId.setResource(Tools.parseResource(message.getFromID().getName())); + TextMessage textMsg = new TextMessage(fromId, message.getBody()); + textMsg.setFrom(fromId); + textMsg.setBody(message.getBody()); + textMsg.setSubject(message.getSubject()); + @SuppressWarnings("unchecked") + Map props = message.getProperties(); + for (Object o : props.keySet()) { + if (o instanceof String) { + String key = (String) o; + Object v = props.get(key); + if (v instanceof String) { + textMsg.setProperty(key, (String) v); + } + } + } + ITextMessageEvent chatEvent = new ChatMessageEvent(textMsg); + + String sessionId = (String) message.getProperties().get( + Tools.PROP_SESSION_ID); + // Now find out who gets the message. If the message doesn't contain + // a session id then assume its a straight text chat message. + if (sessionId == null) { + manager.postEvent(chatEvent); + } else { + // Ok, we have a session id. + ISession session = manager.getSession(sessionId); + if (session != null) { + session.postEvent(chatEvent); + } + } + } + + private void handleConfiguration(String body) { + // Determine if an error has occurred. + if (IHttpdXmppMessage.configErrorPattern.matcher(body).matches()) { + statusHandler.handle( + UFStatus.Priority.ERROR, + this.getCollaborationConfigurationParameterValue(body, + IHttpdXmppMessage.ERROR_PARAMETER_NAME) + + ". Shared Display Sessions have been disabled."); + this.disableSharedDisplaySession(); + // terminate execution + return; + } + + // Validate the configuration. + if (IHttpdXmppMessage.configURLPattern.matcher(body).matches() == false) { + statusHandler + .handle(UFStatus.Priority.PROBLEM, + "Received invalid configuration from openfire. Shared Display Sessions have been disabled."); + this.disableSharedDisplaySession(); + return; + } + + // Remove the parameter name. + String httpdCollaborationURL = this + .getCollaborationConfigurationParameterValue(body, + IHttpdXmppMessage.URL_PARAMETER_NAME); + // validate the url. + if (IHttpdXmppMessage.urlPattern.matcher(httpdCollaborationURL) + .matches() == false) { + statusHandler.handle(UFStatus.Priority.PROBLEM, + "Received an invalid http url from openfire - " + + httpdCollaborationURL + + ". Shared Display Sessions have been disabled."); + this.disableSharedDisplaySession(); + return; + } + + synchronized (httpServerLockObj) { + httpServer = httpdCollaborationURL; + httpServerLockObj.notifyAll(); + } + // configuration is valid; publish it. + IHttpdCollaborationConfigurationEvent configurationEvent = new HttpdCollaborationConfigurationEvent( + httpdCollaborationURL); + manager.postEvent(configurationEvent); + } + + private String getCollaborationConfigurationParameterValue(String body, + String parameterName) { + // Eliminate the preamble. + String encodedConfiguration = body.replace(Tools.CONFIG_PREAMBLE, ""); + // Eliminate the suffix: ]] + encodedConfiguration = encodedConfiguration.substring(0, + encodedConfiguration.length() - 2); + + // Remove the parameter name. + return encodedConfiguration.replace(parameterName + " :", "").trim(); + } + + private void disableSharedDisplaySession() { + // ensure that the shared session displays will be disabled + IHttpdCollaborationConfigurationEvent configurationEvent = new HttpdCollaborationConfigurationEvent( + null); + manager.postEvent(configurationEvent); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/SharedDisplaySession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/SharedDisplaySession.java new file mode 100644 index 0000000000..3663d84eec --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/SharedDisplaySession.java @@ -0,0 +1,139 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import org.eclipse.ecf.core.IContainer; + +import com.google.common.eventbus.EventBus; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 18, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class SharedDisplaySession extends VenueSession implements + ISharedDisplaySession { + + private UserId sessionLeader = null; + + private UserId dataProvider = null; + + public SharedDisplaySession(IContainer container, EventBus externalBus, + CollaborationConnection manager) throws CollaborationException { + super(container, externalBus, manager); + } + + public SharedDisplaySession(IContainer container, EventBus externalBus, + CollaborationConnection manager, String sessionId) + throws CollaborationException { + super(container, externalBus, manager, sessionId); + } + + @Override + public void sendObjectToVenue(Object obj) throws CollaborationException { + if (obj != null) { + String message = Tools.marshallData(obj); + if (message != null) { + sendMessageToVenue(message); + } + } + } + + @Override + public void sendObjectToPeer( + com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID participant, + Object obj) throws CollaborationException { + PeerToPeerChat session = getP2PSession(); + if (session != null) { + String message = Tools.marshallData(obj); + if (message != null) { + TextMessage msg = new TextMessage(participant, message); + msg.setProperty(Tools.PROP_SESSION_ID, getSessionId()); + session.sendPeerToPeer(msg); + } + } + } + + /** + * Get the identification of the user who is the DataProvider. + * + * @return The DataProvider user identification. + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession#getCurrentDataProvider() + */ + @Override + public UserId getCurrentDataProvider() { + return dataProvider; + } + + /** + * Get the identification of the user who is the Session Leader. + * + * @return The Session Leader user identification. + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession#getCurrentSessionLeader() + */ + @Override + public UserId getCurrentSessionLeader() { + return sessionLeader; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession#hasRole(com.raytheon.uf.viz.collaboration.comm.identity.user.ParticipantRole) + */ + @Override + public boolean hasRole(SharedDisplayRole role) { + boolean result = true; + if (role.equals(SharedDisplayRole.DATA_PROVIDER) + && !this.getUserID().equals(this.getCurrentDataProvider())) { + result = false; + } else if (role.equals(SharedDisplayRole.SESSION_LEADER) + && !this.getUserID().equals(this.getCurrentSessionLeader())) { + result = false; + } + return result; + } + + @Override + public void setCurrentSessionLeader(UserId id) { + sessionLeader = id; + } + + @Override + public void setCurrentDataProvider(UserId id) { + dataProvider = id; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java new file mode 100644 index 0000000000..906c9faa47 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/session/VenueSession.java @@ -0,0 +1,527 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.session; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.ContainerConnectException; +import org.eclipse.ecf.core.ContainerCreateException; +import org.eclipse.ecf.core.IContainer; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.identity.IDFactory; +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.IIMMessageEvent; +import org.eclipse.ecf.presence.IIMMessageListener; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.chatroom.IChatRoomContainer; +import org.eclipse.ecf.presence.chatroom.IChatRoomInfo; +import org.eclipse.ecf.presence.chatroom.IChatRoomInvitationSender; +import org.eclipse.ecf.presence.chatroom.IChatRoomManager; +import org.eclipse.ecf.presence.chatroom.IChatRoomMessage; +import org.eclipse.ecf.presence.chatroom.IChatRoomMessageEvent; +import org.eclipse.ecf.presence.chatroom.IChatRoomMessageSender; +import org.eclipse.ecf.presence.chatroom.IChatRoomParticipantListener; + +import com.google.common.eventbus.EventBus; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.Activator; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite; +import com.raytheon.uf.viz.collaboration.comm.provider.CollaborationMessage; +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; +import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueParticipantEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.info.Venue; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * + *
    + *
  • EventBus subscription events.
  • + *
      + *
    • IVenueParticipantEvent : This event is posted when a + * venue participant enters, leaves a venue, or updates their status in the + * venue.
    • + *
    • TextMessage : Text messages send between users. Meant to + * be displayed as conversation.
    • + *
    • CollaborationMessage : These messages are CAVE to CAVE + * command messages.
    • + *
    + *
+ * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * Apr 17, 2012            njensen      Major refactor
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + * @see com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent + * @see com.raytheon.uf.viz.collaboration.comm.provider.TextMessage + * @see com.raytheon.uf.viz.collaboration.comm.provider.CollaborationMessage + */ + +public class VenueSession extends BaseSession implements IVenueSession { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(VenueSession.class); + + private static final String SEND_CMD = "[[COMMAND"; + + private static final String SEND_TXT = "[[TEXT]]"; + + public static final String SEND_HISTORY = "[[HISTORY]]"; + + private IChatRoomInfo venueInfo = null; + + private IChatRoomContainer venueContainer = null; + + private IIMMessageListener intListener = null; + + private IChatRoomParticipantListener participantListener = null; + + private Venue venue; + + /** + * + * @param container + * @param eventBus + */ + protected VenueSession(IContainer container, EventBus externalBus, + CollaborationConnection manager, String sessionId) + throws CollaborationException { + super(container, externalBus, manager, sessionId); + } + + /** + * + * @param container + * @param eventBus + */ + protected VenueSession(IContainer container, EventBus externalBus, + CollaborationConnection manager) throws CollaborationException { + super(container, externalBus, manager); + } + + /** + * Close this session. Closing clears all listeners and disposes of the + * container. No errors for attempting to close an already closed session. + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.ISession#close() + */ + @Override + public void close() { + + if (intListener != null) { + venueContainer.removeMessageListener(intListener); + intListener = null; + } + if (participantListener != null) { + venueContainer + .removeChatRoomParticipantListener(participantListener); + participantListener = null; + } + if (venueContainer != null) { + venueContainer.disconnect(); + venueContainer = null; + } + + venueInfo = null; + + super.close(); + } + + /** + * Get information about this venue. + * + * @return The information about this venue. May return a null reference if + * the venue is not connected. + */ + @Override + public IVenue getVenue() { + return venue; + } + + /** + * Send an invitation from this venue to another user. + * + * @param room + * The target venue for this invitation. + * @param id + * The target user for this invitation. + * @param subject + * The intended subject of the venue conversation. + * @param body + * Any text that the user may wish to include. + * @throws CollaborationException + * @see com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession#sendInvitation(java.lang.String, + * java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public void sendInvitation(UserId id, VenueInvite invite) + throws CollaborationException { + IChatRoomInvitationSender sender = getConnectionPresenceAdapter() + .getChatRoomManager().getInvitationSender(); + if (sender != null) { + String msgBody = Tools.marshallData(invite); + ID roomId = venueInfo.getConnectedID(); + ID userId = IDFactory.getDefault().createID( + getConnectionNamespace(), id.getFQName()); + + try { + sender.sendInvitation(roomId, userId, invite.getSubject(), + msgBody); + } catch (ECFException e) { + throw new CollaborationException("Error sending invitation", e); + } + } + } + + /** + * Send an invitation from this venue to another user. + * + * @param room + * The target venue for this invitation. + * @param id + * The target user for this invitation. + * @param subject + * The intended subject of the venue conversation. + * @param body + * Any text that the user may wish to include. + * @see com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession#sendInvitation(java.lang.String, + * java.lang.String, java.lang.String, java.lang.String) + */ + @Override + public void sendInvitation(List ids, VenueInvite invite) + throws CollaborationException { + if (ids != null) { + for (UserId id : ids) { + sendInvitation(id, invite); + } + } + } + + @Override + public void sendChatMessage(String message) throws CollaborationException { + this.sendMessageToVenue(message); + } + + protected void sendMessageToVenue(String message) + throws CollaborationException { + // Assume success + if ((venueContainer != null) && (message != null)) { + Activator.getDefault().getNetworkStats() + .log(Activator.VENUE, message.length(), 0); + IChatRoomMessageSender sender = venueContainer + .getChatRoomMessageSender(); + try { + if (message.startsWith(SEND_CMD)) { + sender.sendMessage(message); + } else { + sender.sendMessage(SEND_TXT + message); + } + } catch (ECFException e) { + throw new CollaborationException("Error sending messge", e); + } + } + } + + protected IChatRoomInfo joinVenue(String venueName) + throws CollaborationException { + // Create chat room container from manager + IChatRoomManager venueManager = getConnectionPresenceAdapter() + .getChatRoomManager(); + if (venueManager != null) { + venueInfo = venueManager.getChatRoomInfo(venueName); + if (venueInfo == null) { + throw new CollaborationException("Unable to join venue " + + venueName + ". Venue may have been closed already."); + } + completeVenueConnection(venueInfo); + } + return venueInfo; + } + + /** + * This does NOT connect to the room, it only creates the venue and returns + * the info. To connect, connectToRoom must be called. + * + * @param venueName + * @throws CollaborationException + * @throws Exception + * @see com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession#createVenue(java.lang.String, + * java.lang.String) + */ + protected IChatRoomInfo createVenue(String venueName, String subject) + throws CollaborationException { + try { + // Create chat room container from manager + IChatRoomManager venueManager = getConnectionPresenceAdapter() + .getChatRoomManager(); + if (venueManager != null) { + venueInfo = venueManager.getChatRoomInfo(venueName); + if (venueInfo == null) { + Map props = null; + if (subject != null) { + props = new HashMap(); + props.put(Tools.VENUE_SUBJECT_PROP, subject); + } + venueInfo = venueManager.createChatRoom(venueName, props); + completeVenueConnection(venueInfo); + } + } + } catch (Exception e) { + throw new CollaborationException("Error creating venue " + + venueName, e); + } + return venueInfo; + } + + /** + * + * @return + * @throws CollaborationException + */ + private void completeVenueConnection(IChatRoomInfo venueInfo) + throws CollaborationException { + if (venueInfo != null) { + try { + venueContainer = venueInfo.createChatRoomContainer(); + this.venue = new Venue(venueContainer, venueInfo); + } catch (ContainerCreateException e) { + throw new CollaborationException( + "Error completing connection to venue", e); + } + } + } + + /** + * Allows users to connect after the fact so that they do not miss any + * messages coming from the room (after the dialog/view has been + * instanstiated) + */ + public void connectToRoom() { + try { + IChatRoomParticipantListener pListener = new IChatRoomParticipantListener() { + @Override + public void handleArrived(IUser participant) { + UserId user = IDConverter.convertFrom(participant); + postEvent(new VenueParticipantEvent(user, + ParticipantEventType.ARRIVED)); + } + + @Override + public void handleUpdated(IUser participant) { + UserId user = IDConverter.convertFrom(participant); + postEvent(new VenueParticipantEvent(user, + ParticipantEventType.UPDATED)); + } + + @Override + public void handleDeparted(IUser participant) { + UserId user = IDConverter.convertFrom(participant); + postEvent(new VenueParticipantEvent(user, + ParticipantEventType.DEPARTED)); + } + + @Override + public void handlePresenceUpdated(ID fromID, + org.eclipse.ecf.presence.IPresence presence) { + venue.handlePresenceUpdated(fromID, presence); + UserId user = IDConverter.convertFrom(fromID); + postEvent(new VenueParticipantEvent(user, presence, + ParticipantEventType.PRESENCE_UPDATED)); + + } + }; + venueContainer.addChatRoomParticipantListener(pListener); + + venueContainer.connect(venueInfo.getRoomID(), null); + if (venueContainer.getConnectedID() != null) { + + intListener = new IIMMessageListener() { + public void handleMessageEvent(IIMMessageEvent messageEvent) { + if (messageEvent instanceof IChatRoomMessageEvent) { + IChatRoomMessage m = ((IChatRoomMessageEvent) messageEvent) + .getChatRoomMessage(); + Activator + .getDefault() + .getNetworkStats() + .log(Activator.VENUE, 0, + m.getMessage().length()); + if (accept(m)) { + distributeMessage(convertMessage(m)); + } + } + } + }; + venueContainer.addMessageListener(intListener); + + sendPresence(CollaborationConnection.getConnection() + .getPresence()); + } + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } catch (ContainerConnectException e) { + statusHandler.handle(Priority.ERROR, + "Unable to connect to container", e); + } + } + + /** + * Examine the incoming message to determine if it should be forwarded. The + * method looks at the from identifier to determine who sent the message. + * + * @param message + * A message to accept. + * @return Should the message be accepted. + */ + private boolean accept(IChatRoomMessage message) { + boolean acceptMessage = true; + + String body = message.getMessage(); + // Command data only + if (body.startsWith(SEND_CMD)) { + ID from = message.getFromID(); + + String name = Tools.parseName(from.getName()); + + UserId account = getSessionManager().getUser(); + String aName = account.getFQName(); + if (aName.equals(name)) { + acceptMessage = false; + } + } + return acceptMessage; + } + + /** + * + * @param message + */ + private void distributeMessage(IMessage message) { + if (message != null) { + + String body = message.getBody(); + if (body != null) { + if (body.startsWith(SEND_CMD)) { + Object o = null; + try { + o = Tools.unMarshallData(body); + if (o != null) { + this.postEvent(o); + } + } catch (CollaborationException ce) { + statusHandler.error( + "Error deserializing received message on venue " + + venueInfo.getName(), ce); + } + } else if (body.startsWith(SEND_TXT)) { + body = body.substring(SEND_TXT.length()); + message.setBody(body); + + TextMessage msg = new TextMessage(message.getTo(), + message.getBody()); + msg.setFrom(message.getFrom()); + + this.postEvent(msg); + } else if (body.startsWith(SEND_HISTORY)) { + String[] vars = body.split("\\|"); + String timeString = vars[0] + .substring(SEND_HISTORY.length()); + long time = Long.parseLong(timeString); + String username = vars[1]; + String site = vars[2]; + // add the SEND_HISTORY tag length, and the timestamp + // length, username length, and the site length plus the + // three pipe characters + String moddedBody = body.substring(SEND_HISTORY.length() + + timeString.length() + username.length() + + site.length() + SEND_TXT.length() + 3); + message.setBody(moddedBody); + TextMessage msg = new TextMessage(message.getFrom(), + message.getBody()); + UserId id = new UserId(username, CollaborationConnection + .getConnection().getConnectionData().getServer()); + msg.setFrom(id); + msg.setTimeStamp(time); + msg.setSubject(site); + msg.setStatus(SEND_HISTORY); + this.postEvent(msg); + } else { + // attempt to handle outside clients as text only since the + // SEND_TXT won't be appended to the first portion of the + // body + message.setBody(body); + TextMessage msg = new TextMessage(message.getTo(), + message.getBody()); + msg.setFrom(message.getFrom()); + + this.postEvent(msg); + } + } + } + } + + /** + * Convert from an ECF chat room message to an IMessage instance. + * + * @param msg + * The ECF chat room message to convert. + * @return The converted message. + */ + private IMessage convertMessage(IChatRoomMessage msg) { + IMessage message = null; + + String body = msg.getMessage(); + if (body != null) { + message = new CollaborationMessage(null, msg.getMessage()); + message.setFrom(IDConverter.convertFrom(msg.getFromID())); + } + return message; + } + + @Override + public void sendPresence(IPresence presence) throws CollaborationException { + try { + CollaborationConnection.getConnection().getRosterManager() + .getPresenceSender() + .sendPresenceUpdate(venueInfo.getRoomID(), presence); + } catch (ECFException e) { + throw new CollaborationException(e); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/ContactsManager.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/ContactsManager.java new file mode 100644 index 0000000000..e57119b1a0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/ContactsManager.java @@ -0,0 +1,585 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.user; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.xml.bind.JAXB; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.core.user.User; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.ecf.presence.Presence; +import org.eclipse.ecf.presence.roster.IRoster; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.ecf.presence.roster.IRosterItem; +import org.eclipse.ecf.presence.roster.IRosterListener; +import org.eclipse.ecf.presence.search.ICriteria; +import org.eclipse.ecf.presence.search.ICriterion; +import org.eclipse.ecf.presence.search.IResult; +import org.eclipse.ecf.presence.search.ISearch; +import org.eclipse.ecf.presence.search.IUserSearchManager; +import org.eclipse.ecf.presence.search.UserSearchException; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; +import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; + +/** + * + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 29, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +public class ContactsManager { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ContactsManager.class); + + private final Job storeLocalGroupsJob = new Job("Storing Local Groups") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = PathManagerFactory.getPathManager() + .getLocalizationFile( + context, + "collaboration" + File.separator + + "localGroups.xml"); + LocalGroups obj; + synchronized (localGroups) { + obj = new LocalGroups(localGroups); + } + JAXB.marshal(obj, file.getFile()); + try { + file.save(); + } catch (LocalizationOpFailedException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + return org.eclipse.core.runtime.Status.OK_STATUS; + } + }; + + private final CollaborationConnection connection; + + private List localGroups; + + private Map localAliases; + + private Set groupListeners = new HashSet(); + + public ContactsManager(CollaborationConnection connection) { + this.connection = connection; + localAliases = UserIdWrapper.readAliasMap(); + applyLocalAliases(getRoster()); + initLocalGroups(); + connection.getRosterManager().addRosterListener(new IRosterListener() { + + @Override + public void handleRosterUpdate(IRoster roster, + IRosterItem changedValue) { + + } + + @Override + public void handleRosterEntryRemove(IRosterEntry entry) { + + } + + @Override + public void handleRosterEntryAdd(IRosterEntry entry) { + applyLocalAliases(entry); + + } + }); + } + + private void applyLocalAliases(IRosterItem item) { + if (item instanceof IRosterEntry) { + IRosterEntry entry = (IRosterEntry) item; + IUser user = entry.getUser(); + String alias = localAliases.get(getUserId(user)); + if (alias != null && user instanceof User) { + ((User) user).setNickname(alias); + } + } else if (item instanceof IRosterGroup) { + Collection entries = ((IRosterGroup) item).getEntries(); + synchronized (entries) { + entries = new ArrayList(entries); + } + for (Object o : entries) { + applyLocalAliases((IRosterItem) o); + } + } else if (item instanceof IRoster) { + Collection entries = ((IRoster) item).getItems(); + synchronized (entries) { + entries = new ArrayList(entries); + } + for (Object o : entries) { + applyLocalAliases((IRosterItem) o); + } + } + } + + private void initLocalGroups() { + storeLocalGroupsJob.setSystem(true); + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = PathManagerFactory.getPathManager() + .getLocalizationFile(context, + "collaboration" + File.separator + "localGroups.xml"); + if (file.exists()) { + this.localGroups = JAXB + .unmarshal(file.getFile(), LocalGroups.class).getGroups(); + } + + if (this.localGroups == null) { + this.localGroups = new ArrayList(); + } + for (LocalGroup group : localGroups) { + group.setManager(this); + } + } + + public List getLocalGroups() { + synchronized (this.localGroups) { + return new ArrayList(this.localGroups); + } + } + + public void addToLocalGroup(String groupName, IUser user) { + synchronized (this.localGroups) { + LocalGroup group = createLocalGroup(groupName); + String userId = getUserId(user); + List userNames = group.getUserNames(); + if (!userNames.contains(userId)) { + List users = group.getUsers(); + group.getUserNames().add(userId); + users.add(user); + } + IRosterEntry entry = getRosterEntry(user); + if (entry == null || entry.getGroups().isEmpty()) { + // In order to get presence for a user they must be in the + // roster, we can add them to the roster by either subscribing + // to them using presence or adding them to the roster, + // subscribing to the presence will not set the name coreectly + // so we use the roster add method. + try { + // IPresence presence = new Presence(Type.SUBSCRIBE); + // connection.getRosterManager().getPresenceSender() + // .sendPresenceUpdate(user.getID(), presence); + + connection.getRosterManager().getRosterSubscriptionSender() + .sendRosterAdd(userId, user.getName(), null); + } catch (ECFException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + for (LocalGroupListener listener : getSafeGroupListeners()) { + listener.userAdded(group, user); + } + } + storeLocalGroupsJob.schedule(); + } + + public void deleteFromLocalGroup(String groupName, IUser user) { + synchronized (localGroups) { + Iterator it = localGroups.iterator(); + while (it.hasNext()) { + LocalGroup group = it.next(); + if (group.getName().equals(groupName)) { + group.getUsers().remove(user); + group.getUserNames().remove(getUserId(user)); + for (LocalGroupListener listener : getSafeGroupListeners()) { + listener.userDeleted(group, user); + } + break; + } + } + if (getLocalGroups(user).isEmpty()) { + // if the user is in no local groups and no roster groups remove + // them from our roster. + IRosterEntry entry = getRosterEntry(user); + if (entry != null && entry.getGroups().isEmpty()) { + IPresence presence = new Presence(Type.UNSUBSCRIBE); + try { + connection.getRosterManager().getPresenceSender() + .sendPresenceUpdate(user.getID(), presence); + } catch (ECFException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + storeLocalGroupsJob.schedule(); + } + } + + public LocalGroup createLocalGroup(String groupName) { + synchronized (localGroups) { + for (LocalGroup group : this.localGroups) { + if (groupName.equals(group.getName())) { + return group; + } + } + LocalGroup group = new LocalGroup(groupName); + group.setManager(this); + localGroups.add(group); + for (LocalGroupListener listener : getSafeGroupListeners()) { + listener.groupCreated(group); + } + storeLocalGroupsJob.schedule(); + return group; + } + } + + public void deleteLocalGroup(String groupName) { + synchronized (localGroups) { + Iterator it = this.localGroups.iterator(); + while (it.hasNext()) { + LocalGroup group = it.next(); + if (groupName.equals(group.getName())) { + ArrayList users = new ArrayList( + group.getUsers()); + for (IUser user : users) { + deleteFromLocalGroup(groupName, user); + } + it.remove(); + for (LocalGroupListener listener : getSafeGroupListeners()) { + listener.groupDeleted(group); + } + } + } + } + storeLocalGroupsJob.schedule(); + } + + public void renameLocalGroup(String oldName, String newName) { + synchronized (localGroups) { + + for (LocalGroup group : localGroups) { + if (oldName.equals(group.getName())) { + for (LocalGroupListener listener : getSafeGroupListeners()) { + listener.groupDeleted(group); + } + group.setName(newName); + for (LocalGroupListener listener : getSafeGroupListeners()) { + listener.groupCreated(group); + } + } + } + } + storeLocalGroupsJob.schedule(); + } + + public List getLocalGroups(IUser user) { + List results = new ArrayList(); + synchronized (localGroups) { + for (LocalGroup group : localGroups) { + for (String userName : group.getUserNames()) { + if (getUserId(user).equals(userName)) { + results.add(group); + break; + } + } + } + } + return results; + } + + public void setNickname(IUser user, String nickname) { + synchronized (localAliases) { + + localAliases.put(getUserId(user), nickname); + try { + UserIdWrapper.saveAliasMap(localAliases); + } catch (LocalizationOpFailedException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + applyLocalAliases(getRoster()); + connection.postEvent(new UserNicknameChangedEvent(user, nickname)); + } + } + + /** + * Attempt to find a good displayable name for a user, first it looks in the + * local alias file, then it searches the roster to see if the server has + * provided a name, finally if no name is found it will attempt to use the + * username. + * + * @param user + * @return + */ + public String getDisplayName(IUser user) { + String alias = localAliases.get(getUserId(user)); + if (alias == null) { + // at this point try to get the user from roster; + IUser rosterUser = null; + if (user.getID() != null) { + rosterUser = getUser(user.getID()); + } + if (rosterUser != null) { + user = rosterUser; + } + alias = user.getNickname(); + if (alias == null) { + alias = user.getName(); + if (alias == null) { + alias = user.getID().getName(); + } + } + if (alias.contains("@")) { + alias = Tools.parseName(alias); + } + } + return alias; + } + + public IUser getUser(ID id) { + return getUser(getUserId(id)); + } + + public IUser getUser(String userId) { + userId = normalizeId(userId); + IRosterEntry entry = searchRoster(getRoster(), userId); + if (entry == null) { + return null; + } + return entry.getUser(); + } + + public IRosterEntry getRosterEntry(IUser user) { + return searchRoster(user); + } + + public IPresence getPresence(IUser user) { + IRosterEntry entry = searchRoster(user); + if (entry == null) { + return new Presence(Type.UNKNOWN); + } + return entry.getPresence(); + } + + /** + * Used by local groups to make sure all local group items are in the + * roster. + * + * @param name + * @return + */ + protected IUser findAndAddUser(String name) { + name = normalizeId(name); + IUser user = null; + IRosterEntry entry = searchRoster(getRoster(), name); + if (entry != null) { + user = entry.getUser(); + } + if (user == null) { + user = findUser(name); + if (user != null) { + try { + connection + .getRosterManager() + .getRosterSubscriptionSender() + .sendRosterAdd(getUserId(user), user.getName(), + null); + } catch (ECFException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + return user; + + } + + private IUser findUser(String name) { + IUserSearchManager searchManager = connection + .getPresenceContainerAdapter().getUserSearchManager(); + ICriterion criterion = searchManager.createRestriction().eq("Username", + Tools.parseName(name)); + ICriteria criteria = searchManager.createCriteria(); + criteria.add(criterion); + try { + ISearch search = searchManager.search(criteria); + for (Object result : search.getResultList().getResults()) { + if (result instanceof IResult) { + IUser user = ((IResult) result).getUser(); + String alias = localAliases.get(getUserId(user)); + if (alias != null && user instanceof User) { + ((User) user).setNickname(alias); + } + return user; + } + } + } catch (UserSearchException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + return null; + } + + private IRoster getRoster() { + return connection.getRosterManager().getRoster(); + } + + /** + * given a user return username@host. + * + * @param user + * @return + */ + private String getUserId(IUser user) { + if (user.getID() == null) { + return normalizeId(user.toString()); + } + return getUserId(user.getID()); + } + + /** + * given a user ID return username@host. + * + * @param id + * @return + */ + private String getUserId(ID id) { + return normalizeId(id.getName()); + } + + private String normalizeId(String userId) { + String name = Tools.parseName(userId); + String hostname = Tools.parseHost(userId); + hostname = IDConverter.normalizeHostname(hostname); + return name + "@" + hostname; + } + + private IRosterEntry searchRoster(IUser user) { + String userId = getUserId(user); + return searchRoster(getRoster(), userId); + } + + private IRosterEntry searchRoster(IRosterItem item, String userName) { + if (item instanceof IRosterEntry) { + IRosterEntry entry = (IRosterEntry) item; + if (userName.equals(getUserId(entry.getUser()))) { + return entry; + } + } else if (item instanceof IRosterGroup) { + Collection entries = ((IRosterGroup) item).getEntries(); + synchronized (entries) { + entries = new ArrayList(entries); + } + for (Object o : entries) { + IRosterEntry entry = searchRoster((IRosterItem) o, userName); + if (entry != null) { + return entry; + } + } + } else if (item instanceof IRoster) { + Collection entries = ((IRoster) item).getItems(); + synchronized (entries) { + entries = new ArrayList(entries); + } + for (Object o : entries) { + IRosterEntry entry = searchRoster((IRosterItem) o, userName); + if (entry != null) { + return entry; + } + } + } else { + throw new IllegalStateException("Unexpected Roster entry: " + + item.getClass().getSimpleName()); + } + return null; + } + + public void addLocalGroupListener(LocalGroupListener listener) { + synchronized (groupListeners) { + groupListeners.add(listener); + } + } + + public void removeLocalGroupListener(LocalGroupListener listener) { + synchronized (groupListeners) { + groupListeners.remove(listener); + } + } + + protected Set getSafeGroupListeners() { + Set safeSet = new HashSet(); + synchronized (groupListeners) { + safeSet.addAll(groupListeners); + } + return safeSet; + } + + public static interface LocalGroupListener { + + public void groupCreated(LocalGroup group); + + public void groupDeleted(LocalGroup group); + + public void userAdded(LocalGroup group, IUser user); + + public void userDeleted(LocalGroup group, IUser user); + + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/IDConverter.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/IDConverter.java new file mode 100644 index 0000000000..c29d5b63e3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/IDConverter.java @@ -0,0 +1,90 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.user; + +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 28, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class IDConverter { + + private static final String CONF_ID = "conference."; + + /** + * + * @param user + * @return + */ + public static UserId convertFrom(org.eclipse.ecf.core.identity.ID id) { + String name = Tools.parseName(id.getName()); + String host = Tools.parseHost(id.getName()); + String rsc = Tools.parseResource(id.getName()); + + UserId uid = new UserId(name, host, rsc); + uid.setId(id); + return uid; + } + + /** + * + * @param user + * @return + */ + public static UserId convertFrom(org.eclipse.ecf.core.user.IUser user) { + UserId retVal = null; + if (user instanceof UserId) { + retVal = (UserId) user; + } else { + String name = Tools.parseName(user.getID().getName()); + String host = Tools.parseHost(user.getID().getName()); + retVal = new UserId(name, host); + retVal.setId(user.getID()); + if (user.getNickname() != null) { + retVal.setAlias(user.getNickname()); + } else { + retVal.setAlias(user.getName()); + } + } + return retVal; + } + + public static String normalizeHostname(String hostname) { + if (hostname.startsWith(CONF_ID)) { + return hostname.substring(CONF_ID.length()); + } + return hostname; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/LocalGroups.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/LocalGroups.java new file mode 100644 index 0000000000..e8efeb159b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/LocalGroups.java @@ -0,0 +1,133 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.user; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlTransient; + +import org.eclipse.ecf.core.user.IUser; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 2, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "LocalGroups") +public class LocalGroups { + + @XmlElement(name = "group") + private List groups; + + public LocalGroups() { + } + + public LocalGroups(List groups) { + this.groups = new ArrayList(groups); + } + + public List getGroups() { + return groups; + } + + public void setGroups(List groups) { + this.groups = groups; + } + + @XmlAccessorType(XmlAccessType.NONE) + public static class LocalGroup { + + @XmlAttribute + private String name; + + @XmlElement(name = "user") + private List userNames; + + @XmlTransient + private ContactsManager manager; + + @XmlTransient + private List users; + + public LocalGroup() { + } + + public LocalGroup(String name) { + this.name = name; + this.userNames = new ArrayList(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getUserNames() { + if (userNames == null) { + userNames = new ArrayList(); + } + return userNames; + } + + public void setUserNames(List userNames) { + this.userNames = userNames; + } + + public synchronized List getUsers() { + if (users == null) { + users = new ArrayList(); + for (String userName : userNames) { + IUser user = manager.findAndAddUser(userName); + if (user != null) { + users.add(user); + } + } + } + return users; + } + + public void setManager(ContactsManager manager) { + this.manager = manager; + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/UserId.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/UserId.java new file mode 100644 index 0000000000..1b135258a9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/UserId.java @@ -0,0 +1,279 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.user; + +import java.util.Map; + +import javax.xml.bind.annotation.XmlRootElement; + +import org.eclipse.ecf.core.identity.ID; +import org.eclipse.ecf.core.user.IUser; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            jkorman     Initial creation
+ * Apr 18, 2012            njensen      Major refactor
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ +@DynamicSerialize +@XmlRootElement(name = "userId") +public class UserId implements IQualifiedID, IUser { + + @DynamicSerializeElement + protected String name; + + @DynamicSerializeElement + protected String host; + + @DynamicSerializeElement + protected String resource; + + @DynamicSerializeElement + protected String alias; + + private ID id; + + public UserId() { + + } + + /** + * + * @param userName + * @param hostName + */ + public UserId(String userName, String hostName) { + this(userName, hostName, null); + } + + /** + * + * @param userName + * @param hostName + * @param resourceName + */ + public UserId(String userName, String hostName, String resource) { + this(userName, hostName, resource, null); + } + + public UserId(String userName, String hostName, String resource, + String alias) { + this.name = userName; + setHost(hostName); + this.resource = resource; + this.alias = alias; + } + + /** + * @param userName + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#setUserName(java.lang.String) + */ + @Override + public void setName(String userName) { + name = userName; + } + + /** + * @return The user name associated with this id. + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#getUserName() + */ + @Override + public String getName() { + return name; + } + + /** + * + * @param hostName + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#setHostName(java.lang.String) + */ + @Override + public void setHost(String hostname) { + host = IDConverter.normalizeHostname(hostname); + } + + /** + * + * @return The host name associated with this id. + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#getHostName() + */ + @Override + public String getHost() { + return host; + } + + /** + * + * @param resourceName + * The resource associated with this id. + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#setResourceName(java.lang.String) + */ + @Override + public void setResource(String resourceName) { + resource = resourceName; + } + + /** + * + * @return The resource associated with this id. + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#getResource() + */ + @Override + public String getResource() { + return resource; + } + + /** + * + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#getFQName() + */ + @Override + public String getFQName() { + StringBuilder sb = new StringBuilder(name); + sb.append("@"); + sb.append(host); + sb.append("/"); + if (resource != null) { + sb.append(resource); + } else { + // TODO need a better way around this ECF/XMPP flaw that is + // requiring a resource for peerToPeer to go through + sb.append("resource"); + } + return sb.toString(); + } + + public String getAlias() { + if (alias == null || alias.isEmpty()) { + return name; + } + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + @Override + public String toString() { + return this.getFQName(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((host == null) ? 0 : host.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + + ((resource == null) ? 0 : resource.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (!(obj instanceof UserId)) + return false; + UserId other = (UserId) obj; + if (host == null) { + if (other.host != null) + return false; + } else if (!host.equals(other.host)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (resource == null) { + if (other.resource != null) + return false; + } else if (!resource.equals(other.resource)) + return false; + return true; + } + + @Override + public Object getAdapter(Class adapter) { + return null; + } + + @Override + public String getNickname() { + return alias; + } + + @Override + public Map getProperties() { + return null; + } + + @Override + public ID getID() { + return id; + } + + /** + * @param id + * the id to set + */ + public void setId(ID id) { + this.id = id; + } + + /** + * Checks if it is the same user. Does not check the resource. + * + * @param id + * the string id to compare against + * @return if it is the same user + */ + public boolean isSameUser(String id) { + boolean result = false; + String name = Tools.parseName(id); + String host = Tools.parseHost(id); + if (name != null && host != null) { + if (this.name.equals(name) && this.host.equals(host)) { + result = true; + } + } + return result; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/UserIdWrapper.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/UserIdWrapper.java new file mode 100644 index 0000000000..da59577cb8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/UserIdWrapper.java @@ -0,0 +1,119 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.user; + +import java.io.File; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.xml.bind.JAXB; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 30, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class UserIdWrapper { + @DynamicSerializeElement + private UserId[] userIds; + + /** + * @param userIds + * the userIds to set + */ + public void setUserIds(UserId[] userIds) { + this.userIds = userIds; + } + + /** + * @return the userIds + */ + public UserId[] getUserIds() { + return userIds; + } + + public static Map readAliasMap() { + Map result = new HashMap(); + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = PathManagerFactory.getPathManager() + .getLocalizationFile( + context, + "collaboration" + File.separator + + "collaborationAliases.xml"); + if (file.exists()) { + UserIdWrapper ids = (UserIdWrapper) JAXB.unmarshal(file.getFile(), + UserIdWrapper.class); + if (ids.getUserIds() != null) { + for (UserId id : ids.getUserIds()) { + result.put(id.getName() + "@" + id.getHost(), id.getAlias()); + } + } + } + return result; + } + + public static void saveAliasMap(Map localAliases) + throws LocalizationOpFailedException { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = pm.getLocalizationFile(context, "collaboration" + + File.separator + "collaborationAliases.xml"); + Set ids = new HashSet(); + for (Entry entry : localAliases.entrySet()) { + ids.add(new UserId(Tools.parseName(entry.getKey()), Tools + .parseHost(entry.getKey()), null, entry.getValue())); + } + UserIdWrapper wrapper = new UserIdWrapper(); + wrapper.setUserIds(ids.toArray(new UserId[0])); + JAXB.marshal(wrapper, file.getFile()); + file.save(); + + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/VenueId.java b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/VenueId.java new file mode 100644 index 0000000000..cdfcff26b5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.comm/src/com/raytheon/uf/viz/collaboration/comm/provider/user/VenueId.java @@ -0,0 +1,116 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.comm.provider.user; + +import com.raytheon.uf.viz.collaboration.comm.identity.user.IVenueId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 29, 2012            jkorman     Initial creation
+ * 
+ * 
+ * + * @author jkorman + * @version 1.0 + */ + +public class VenueId implements IVenueId { + + private String host; + + private String resource; + + private String venueName; + + private String name; + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#setHost(java.lang.String) + */ + @Override + public void setHost(String hostName) { + host = hostName; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#getHost() + */ + @Override + public String getHost() { + return host; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#setResource(java.lang.String) + */ + @Override + public void setResource(String resource) { + this.resource = resource; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID#getResource() + */ + @Override + public String getResource() { + return resource; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.ID#setName(java.lang.String) + */ + @Override + public void setName(String userName) { + name = userName; + venueName = name; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.ID#getName() + */ + @Override + public String getName() { + return name; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.ID#getFQName() + */ + @Override + public String getFQName() { + return null; + } + + /** + * @see com.raytheon.uf.viz.collaboration.comm.identity.user.IVenueId#getVenueName() + */ + @Override + public String getVenueName() { + return venueName; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/.classpath b/cave/com.raytheon.uf.viz.collaboration.core.ui/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/.project b/cave/com.raytheon.uf.viz.collaboration.core.ui/.project new file mode 100644 index 0000000000..d7dd120bdd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.core.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.core.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..13a4fe183d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Tue Jun 26 11:21:58 CDT 2012 +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/cave/com.raytheon.uf.viz.collaboration.core.ui/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.core.ui/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..76e663d876 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/META-INF/MANIFEST.MF @@ -0,0 +1,14 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Collaboration Core UI +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.core.ui +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.core.ui.Activator +Bundle-Vendor: RAYTHEON +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.collaboration.comm;bundle-version="1.0.0", + org.eclipse.ecf.presence;bundle-version="2.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.collaboration.core.ui diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/build.properties b/cave/com.raytheon.uf.viz.collaboration.core.ui/build.properties new file mode 100644 index 0000000000..c6baffa001 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + icons/ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/add_collaborate.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/add_collaborate.gif new file mode 100644 index 0000000000..0840bc6094 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/add_collaborate.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/chats.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/chats.gif new file mode 100644 index 0000000000..21a902fd1a Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/chats.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/collapseall.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/collapseall.gif new file mode 100644 index 0000000000..a2d80a9044 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/collapseall.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/feed.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/feed.gif new file mode 100644 index 0000000000..cdf4e8f36e Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/feed.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/font.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/font.gif new file mode 100644 index 0000000000..2c24792a5e Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/font.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/group.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/group.gif new file mode 100644 index 0000000000..f9635268ed Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/group.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/log.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/log.gif new file mode 100644 index 0000000000..bc1f18500b Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/log.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/login.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/login.gif new file mode 100644 index 0000000000..f7907e56d1 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/login.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/logout.gif b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/logout.gif new file mode 100644 index 0000000000..dc47edf069 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.core.ui/icons/logout.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/Activator.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/Activator.java new file mode 100644 index 0000000000..22f57e959e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/Activator.java @@ -0,0 +1,50 @@ +package com.raytheon.uf.viz.collaboration.core.ui; + +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.raytheon.uf.viz.collaboration.core.ui"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * 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; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/CollaborationGroupControl.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/CollaborationGroupControl.java new file mode 100644 index 0000000000..cc12ab018f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/CollaborationGroupControl.java @@ -0,0 +1,295 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.swing.tree.TreePath; + +import org.eclipse.ecf.presence.roster.IRoster; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.graphics.Image; +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.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.plugin.AbstractUIPlugin; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.core.ui.data.ActiveSessionsTreeData; +import com.raytheon.uf.viz.collaboration.core.ui.data.MyUserTreeData; +import com.raytheon.uf.viz.collaboration.core.ui.data.UserGroupTreeData; +import com.raytheon.uf.viz.collaboration.core.ui.tree.UsersTreeContentProvider; +import com.raytheon.uf.viz.collaboration.core.ui.tree.UsersTreeLabelProvider; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationGroupControl { + + private Text filterText; + + private TreeViewer usersTreeViewer; + + private IMenuManager mainMenu; + + private ICollaborationUIManager manager; + + private ActiveSessionsTreeData activeSessions; + + private MyUserTreeData myUserData; + + private List groups = new ArrayList(); + + public CollaborationGroupControl(Composite compsite, + ICollaborationUIManager manager) { + this.manager = manager; + initializeGroupControl(compsite); + manager.getConnection().registerEventHandler(this); + } + + /** + * @param parent + */ + private void initializeGroupControl(Composite parent) { + parent.setLayout(new GridLayout()); + createFilterText(parent); + createUserTree(parent); + + createMainMenu(); + } + + /** + * @param parent + */ + private void createUserTree(Composite parent) { + Composite treeComp = new Composite(parent, SWT.NONE); + treeComp.setLayout(new GridLayout(1, false)); + treeComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + Tree tree = new Tree(treeComp, SWT.VIRTUAL | SWT.MULTI | SWT.V_SCROLL + | SWT.H_SCROLL | SWT.BORDER); + tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // any width would work + new TreeColumn(tree, SWT.NONE).setWidth(200); + + MenuManager menuMgr = new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + public void menuAboutToShow(IMenuManager mgr) { + fillContextMenu(mgr); + } + }); + Menu menu = menuMgr.createContextMenu(tree); + tree.setMenu(menu); + + usersTreeViewer = new TreeViewer(tree); + usersTreeViewer.setContentProvider(new UsersTreeContentProvider()); + usersTreeViewer.setLabelProvider(new UsersTreeLabelProvider()); + populateTree(); + } + + private void populateTree() { + if (myUserData == null) { + myUserData = new MyUserTreeData(CollaborationConnection + .getConnection().getUser()); + activeSessions = new ActiveSessionsTreeData(); + usersTreeViewer.add(new TreePath(new Object[0]), new Object[] { + myUserData, activeSessions }); + } + usersTreeViewer.remove(groups.toArray(new Object[groups.size()])); + groups.clear(); + populateGroups(); + } + + /** + * + */ + private void populateGroups() { + Map dataMap = new HashMap(); + IRoster roster = CollaborationConnection.getConnection() + .getRosterManager().getRoster(); + for (Object item : roster.getItems()) { + if (item instanceof IRosterGroup) { + IRosterGroup group = (IRosterGroup) item; + } else if (item instanceof IRosterEntry) { + IRosterEntry entry = (IRosterEntry) item; + } + } + } + + private void fillContextMenu(IMenuManager mgr) { + // TODO: Fill context menu based on selected tree items + } + + /** + * + */ + private void createFilterText(Composite parent) { + Composite comp = new Composite(parent, SWT.BORDER); + comp.setBackground(Display.getCurrent().getSystemColor( + SWT.COLOR_LIST_BACKGROUND)); + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + comp.setLayout(layout); + GridData gd = new GridData(SWT.FILL, SWT.NONE, true, false); + comp.setLayoutData(gd); + + filterText = new Text(comp, SWT.SINGLE | SWT.NONE); + GridData data = new GridData(SWT.FILL, SWT.NONE, true, false); + filterText.setLayoutData(data); + filterText.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + filter(); + } + }); + + // Load icons to be used for label button + final Image inactiveImage = AbstractUIPlugin.imageDescriptorFromPlugin( + PlatformUI.PLUGIN_ID, "$nl$/icons/full/dtool16/clear_co.gif") + .createImage(); + final Image activeImage = AbstractUIPlugin.imageDescriptorFromPlugin( + PlatformUI.PLUGIN_ID, "$nl$/icons/full/etool16/clear_co.gif") + .createImage(); + + final Label clearButton = new Label(comp, SWT.NONE); + clearButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, + false, false)); + clearButton.setImage(inactiveImage); + clearButton.setBackground(parent.getDisplay().getSystemColor( + SWT.COLOR_LIST_BACKGROUND)); + clearButton.setToolTipText("Clear text"); + // Add listener for enter/exit changing icon + clearButton.addMouseTrackListener(new MouseTrackAdapter() { + public void mouseEnter(MouseEvent e) { + clearButton.setImage(activeImage); + } + + public void mouseExit(MouseEvent e) { + clearButton.setImage(inactiveImage); + } + }); + // Add mouse listener for clear pressed + clearButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseUp(MouseEvent e) { + filterText.setText(""); + filter(); + } + }); + // Add dispose listener + clearButton.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + inactiveImage.dispose(); + activeImage.dispose(); + } + }); + } + + private void createMainMenu() { + // TODO: Populate the main menu + } + + /** + * Get the {@link Tree} object that contains user information for the + * control + * + * @return + */ + public Tree getUserTree() { + return usersTreeViewer.getTree(); + } + + /** + * Gets the contribution items for the group main menu + * + * @return + */ + public IContributionItem[] getMainMenuItems() { + return mainMenu.getItems(); + } + + /** + * Filters the group view based on the text + * + * @param text + */ + private void filter() { + String currText = filterText.getText(); + // TODO: Filter the visible tree objects + } + + @Subscribe + public void handleRosterChangeEvent(IRosterChangeEvent rosterChangeEvent) { + // TODO: Handle roster events + switch (rosterChangeEvent.getType()) { + case ADD: + break; + case MODIFY: + break; + case DELETE: + break; + case PRESENCE: + break; + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/CollaborationIconFactory.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/CollaborationIconFactory.java new file mode 100644 index 0000000000..fb27f67295 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/CollaborationIconFactory.java @@ -0,0 +1,55 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui; + +import java.io.File; +import java.net.URL; + +import org.eclipse.core.runtime.FileLocator; +import org.eclipse.core.runtime.Path; +import org.eclipse.jface.resource.ImageDescriptor; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationIconFactory { + + public static ImageDescriptor getIconImage(String iconName) { + String path = "icons" + File.separator + iconName; + URL url = FileLocator.find(Activator.getDefault().getBundle(), + new Path(path), null); + return ImageDescriptor.createFromURL(url); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/ICollaborationUIManager.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/ICollaborationUIManager.java new file mode 100644 index 0000000000..4066c51462 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/ICollaborationUIManager.java @@ -0,0 +1,47 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface ICollaborationUIManager { + + public CollaborationConnection getConnection(); + + public void logout(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/AbstractCollaborationAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/AbstractCollaborationAction.java new file mode 100644 index 0000000000..4d4d31dd10 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/AbstractCollaborationAction.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import org.eclipse.jface.action.Action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public abstract class AbstractCollaborationAction extends Action { + + protected CollaborationGroupControl control; + + void setControl(CollaborationGroupControl control) { + this.control = control; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public final void run() { + run(control); + } + + public abstract void run(CollaborationGroupControl control); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/AliasAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/AliasAction.java new file mode 100644 index 0000000000..6cf069b021 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/AliasAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class AliasAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangeFontAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangeFontAction.java new file mode 100644 index 0000000000..95dcf6172d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangeFontAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ChangeFontAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangePasswordAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangePasswordAction.java new file mode 100644 index 0000000000..224e1e524a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangePasswordAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ChangePasswordAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangeStatusMessageAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangeStatusMessageAction.java new file mode 100644 index 0000000000..aafd665442 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChangeStatusMessageAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ChangeStatusMessageAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseRoleAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseRoleAction.java new file mode 100644 index 0000000000..cabb0ba9d8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseRoleAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ChooseRoleAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseSiteAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseSiteAction.java new file mode 100644 index 0000000000..0819c6b65d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseSiteAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ChooseSiteAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseStatusAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseStatusAction.java new file mode 100644 index 0000000000..417606938a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ChooseStatusAction.java @@ -0,0 +1,55 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ChooseStatusAction extends AbstractCollaborationAction { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction + * #run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CollaborationActionFactory.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CollaborationActionFactory.java new file mode 100644 index 0000000000..97002f81e1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CollaborationActionFactory.java @@ -0,0 +1,163 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import static com.raytheon.uf.viz.collaboration.core.ui.CollaborationIconFactory.getIconImage; + +import org.eclipse.jface.action.Action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * Factory for constructing core collaboration ui functionality actions + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationActionFactory { + + public static Action createAliasAction(CollaborationGroupControl control) { + AbstractCollaborationAction action = new AliasAction(); + action.setControl(control); + action.setText("Alias..."); + // TODO: Find Alias image + action.setImageDescriptor(getIconImage("alias.gif")); + return action; + } + + public static Action createChangeFontAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new ChangeFontAction(); + action.setControl(control); + action.setText("Change Font..."); + action.setImageDescriptor(getIconImage("font.gif")); + return action; + } + + public static Action createChangePasswordAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new ChangePasswordAction(); + action.setControl(control); + action.setText("Change Password..."); + return action; + } + + public static Action createChooseRoleAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new ChooseRoleAction(); + action.setControl(control); + action.setText("Change Role"); + return action; + } + + public static Action createChooseSiteAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new ChooseSiteAction(); + action.setControl(control); + action.setText("Change Site"); + return action; + } + + public static Action createChooseStatusAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new ChooseStatusAction(); + action.setControl(control); + action.setText("Change Status"); + return action; + } + + public static Action createCollapseAllAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new CollapseAllAction(); + action.setControl(control); + action.setText("Collapse All..."); + action.setImageDescriptor(getIconImage("collapseall.gif")); + return action; + } + + public static Action createCreateGroupAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new CreateGroupAction(); + action.setControl(control); + action.setText("Create Group..."); + action.setImageDescriptor(getIconImage("group.gif")); + return action; + } + + public static Action createCreateSessionAction( + CollaborationGroupControl control) { + AbstractCollaborationAction action = new CreateSessionAction(); + action.setControl(control); + action.setText("Create Session..."); + action.setImageDescriptor(getIconImage("add_collaborate.gif")); + return action; + } + + public static Action createLoginAction(CollaborationGroupControl control) { + AbstractCollaborationAction action = new LogoutAction(); + action.setControl(control); + action.setText("Login"); + action.setImageDescriptor(getIconImage("login.gif")); + return action; + } + + public static Action createLogoutAction(CollaborationGroupControl control) { + AbstractCollaborationAction action = new LogoutAction(); + action.setControl(control); + action.setText("Logout"); + action.setImageDescriptor(getIconImage("logout.gif")); + return action; + } + + public static Action createP2PChatAction(CollaborationGroupControl control) { + AbstractCollaborationAction action = new P2PChatAction(); + action.setControl(control); + action.setText("Chat..."); + action.setImageDescriptor(getIconImage("chats.gif")); + return action; + } + + public static Action createShowFeedAction(CollaborationGroupControl control) { + AbstractCollaborationAction action = new ShowFeedAction(); + action.setControl(control); + action.setText("Display Feed..."); + action.setImageDescriptor(getIconImage("feed.gif")); + return action; + } + + public static Action createViewLogAction(CollaborationGroupControl control) { + AbstractCollaborationAction action = new ViewLogAction(); + action.setControl(control); + action.setText("View Log..."); + action.setImageDescriptor(getIconImage("log.gif")); + return action; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CollapseAllAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CollapseAllAction.java new file mode 100644 index 0000000000..5a3ee3bf75 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CollapseAllAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollapseAllAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CreateGroupAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CreateGroupAction.java new file mode 100644 index 0000000000..8c74a626ae --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CreateGroupAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CreateGroupAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CreateSessionAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CreateSessionAction.java new file mode 100644 index 0000000000..d9bcb797c8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/CreateSessionAction.java @@ -0,0 +1,55 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CreateSessionAction extends AbstractCollaborationAction { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction + * #run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Create session + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/LoginAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/LoginAction.java new file mode 100644 index 0000000000..9fd81c100e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/LoginAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class LoginAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/LogoutAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/LogoutAction.java new file mode 100644 index 0000000000..df1680ae2a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/LogoutAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class LogoutAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/P2PChatAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/P2PChatAction.java new file mode 100644 index 0000000000..71485560e7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/P2PChatAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class P2PChatAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ShowFeedAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ShowFeedAction.java new file mode 100644 index 0000000000..d1e80bc5dc --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ShowFeedAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ShowFeedAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ViewLogAction.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ViewLogAction.java new file mode 100644 index 0000000000..e754eaf91f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/action/ViewLogAction.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.action; + +import com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ViewLogAction extends AbstractCollaborationAction { + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.collaboration.core.ui.action.AbstractCollaborationAction#run(com.raytheon.uf.viz.collaboration.core.ui.CollaborationGroupControl) + */ + @Override + public void run(CollaborationGroupControl control) { + // TODO Auto-generated method stub + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/ActiveSessionsTreeData.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/ActiveSessionsTreeData.java new file mode 100644 index 0000000000..e20c522d8d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/ActiveSessionsTreeData.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.data; + +/** + * TODO Add Description + * + *
+ *
+ * SOFTWARE HISTORY
+ *
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ *
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ActiveSessionsTreeData { + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/MyUserTreeData.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/MyUserTreeData.java new file mode 100644 index 0000000000..fc781860da --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/MyUserTreeData.java @@ -0,0 +1,56 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.data; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class MyUserTreeData { + + private UserId user; + + public MyUserTreeData(UserId user) { + this.user = user; + } + + /** + * @return the user + */ + public UserId getUser() { + return user; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/UserGroupTreeData.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/UserGroupTreeData.java new file mode 100644 index 0000000000..f58665d83d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/UserGroupTreeData.java @@ -0,0 +1,83 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.data; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class UserGroupTreeData { + + private String groupName; + + private IRosterGroup group; + + private List groupUsers; + + public UserGroupTreeData(String groupName, IRosterGroup group) { + this.groupName = groupName; + this.group = group; + this.groupUsers = new ArrayList(); + } + + /** + * @return the groupName + */ + public String getGroupName() { + return groupName; + } + + /** + * @return the groupUsers + */ + public List getGroupUsers() { + return new ArrayList(groupUsers); + } + + /** + * Adds a user to this group + * + * @param user + */ + public void addUserToGroup(UserId user, IRosterEntry entry) { + groupUsers.add(new UserTreeData(user, entry)); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/UserTreeData.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/UserTreeData.java new file mode 100644 index 0000000000..0fe6606411 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/data/UserTreeData.java @@ -0,0 +1,61 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.data; + +import org.eclipse.ecf.presence.roster.IRosterEntry; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class UserTreeData { + + private UserId user; + + private IRosterEntry userEntry; + + public UserTreeData(UserId user, IRosterEntry userEntry) { + this.user = user; + this.userEntry = userEntry; + } + + /** + * @return the user + */ + public UserId getUser() { + return user; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/tree/UsersTreeContentProvider.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/tree/UsersTreeContentProvider.java new file mode 100644 index 0000000000..f7aaf71e6a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/tree/UsersTreeContentProvider.java @@ -0,0 +1,114 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.tree; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class UsersTreeContentProvider implements ITreeContentProvider { + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + @Override + public void dispose() { + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface + * .viewers.Viewer, java.lang.Object, java.lang.Object) + */ + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang. + * Object) + */ + @Override + public Object[] getElements(Object inputElement) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang. + * Object) + */ + @Override + public Object[] getChildren(Object parentElement) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object + * ) + */ + @Override + public Object getParent(Object element) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang. + * Object) + */ + @Override + public boolean hasChildren(Object element) { + return false; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/tree/UsersTreeLabelProvider.java b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/tree/UsersTreeLabelProvider.java new file mode 100644 index 0000000000..2f66a248b4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.core.ui/src/com/raytheon/uf/viz/collaboration/core/ui/tree/UsersTreeLabelProvider.java @@ -0,0 +1,110 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.core.ui.tree; + +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Image; + +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.core.ui.data.ActiveSessionsTreeData; +import com.raytheon.uf.viz.collaboration.core.ui.data.MyUserTreeData; +import com.raytheon.uf.viz.collaboration.core.ui.data.UserGroupTreeData; +import com.raytheon.uf.viz.collaboration.core.ui.data.UserTreeData; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class UsersTreeLabelProvider extends ColumnLabelProvider { + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ColumnLabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + Image image = null; + if (element instanceof UserTreeData) { + + } else if (element instanceof MyUserTreeData) { + + } else if (element instanceof UserGroupTreeData) { + + } else if (element instanceof ActiveSessionsTreeData) { + + } + return image; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ColumnLabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + String text = null; + if (element instanceof UserTreeData) { + text = formatUserId(((UserTreeData) element).getUser()); + } else if (element instanceof MyUserTreeData) { + text = formatUserId(((UserTreeData) element).getUser()) + + " - " + + CollaborationConnection.getConnection() + .getConnectionData().getServer(); + } else if (element instanceof UserGroupTreeData) { + text = ((UserGroupTreeData) element).getGroupName(); + } else if (element instanceof ActiveSessionsTreeData) { + text = "Active Sessions"; + } + return text; + } + + public static String formatUserId(UserId user) { + Object site = user.getProperties().get(SiteConfigInformation.SITE_NAME); + Object role = user.getProperties().get(SiteConfigInformation.ROLE_NAME); + String name = (user.getAlias() != null ? user.getAlias() : user + .getName()); + if (site != null) { + name += " - " + site; + } + if (role != null) { + name += " - " + role; + } + return name; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/.classpath b/cave/com.raytheon.uf.viz.collaboration.display/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.display/.project b/cave/com.raytheon.uf.viz.collaboration.display/.project new file mode 100644 index 0000000000..20968cc23f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.display + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.display/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.display/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..c94506db44 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Apr 27 11:08:58 CDT 2012 +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/cave/com.raytheon.uf.viz.collaboration.display/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.display/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..0c69688b99 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/META-INF/MANIFEST.MF @@ -0,0 +1,35 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Display +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.display;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.display.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Require-Bundle: org.eclipse.core.runtime, + com.raytheon.uf.viz.core, + com.raytheon.viz.ui, + org.eclipse.ui;bundle-version="3.6.1", + com.raytheon.uf.viz.collaboration.comm, + com.raytheon.uf.common.colormap;bundle-version="1.12.1174", + com.raytheon.uf.viz.remote.graphics;bundle-version="1.0.0", + com.raytheon.uf.viz.drawing;bundle-version="1.0.0", + com.raytheon.uf.common.comm;bundle-version="1.12.1174", + com.raytheon.uf.common.time;bundle-version="1.12.1174", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + com.raytheon.uf.common.util;bundle-version="1.12.1174", + com.raytheon.viz.core;bundle-version="1.12.1174" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.collaboration.display, + com.raytheon.uf.viz.collaboration.display.data, + com.raytheon.uf.viz.collaboration.display.editor, + com.raytheon.uf.viz.collaboration.display.roles, + com.raytheon.uf.viz.collaboration.display.roles.dataprovider, + com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event, + com.raytheon.uf.viz.collaboration.display.roles.dataprovider.rsc, + com.raytheon.uf.viz.collaboration.display.rsc, + com.raytheon.uf.viz.collaboration.display.rsc.event, + com.raytheon.uf.viz.collaboration.display.rsc.rendering, + com.raytheon.uf.viz.collaboration.display.rsc.telestrator +Import-Package: org.eclipse.swt.widgets diff --git a/cave/com.raytheon.uf.viz.collaboration.display/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/cave/com.raytheon.uf.viz.collaboration.display/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject new file mode 100644 index 0000000000..90d61b4ecf --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -0,0 +1,7 @@ +com.raytheon.uf.viz.collaboration.display.editor.CreateRemoteDisplay +com.raytheon.uf.viz.collaboration.display.roles.dataprovider.rsc.DataProviderRscData +com.raytheon.uf.viz.collaboration.display.rsc.CollaborationWrapperResourceData +com.raytheon.uf.viz.collaboration.display.rsc.event.SharedResource +com.raytheon.uf.viz.collaboration.display.rsc.event.ResourceCapabilityChanged +com.raytheon.uf.viz.collaboration.display.rsc.event.ResourcePropertiesChanged +com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingResourceData \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.display/build.properties b/cave/com.raytheon.uf.viz.collaboration.display/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.display/plugin.xml b/cave/com.raytheon.uf.viz.collaboration.display/plugin.xml new file mode 100644 index 0000000000..b77d894ab6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/plugin.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.display/schema/renderingExtension.exsd b/cave/com.raytheon.uf.viz.collaboration.display/schema/renderingExtension.exsd new file mode 100644 index 0000000000..f4b4fa245a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/schema/renderingExtension.exsd @@ -0,0 +1,102 @@ + + + + + + + + + Defines rendering handler objects that use @Subscribe tags to handle render events + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [Enter the first release in which this extension point appears.] + + + + + + + + + [Enter extension point usage example here.] + + + + + + + + + [Enter API information here.] + + + + + + + + + [Enter information about supplied implementation of this extension point.] + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/Activator.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/Activator.java new file mode 100644 index 0000000000..18bcb0917d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/Activator.java @@ -0,0 +1,49 @@ +package com.raytheon.uf.viz.collaboration.display; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.viz.core.jobs.StatsJob; + +public class Activator implements BundleActivator { + + public static final IUFStatusHandler statusHandler = UFStatus + .getHandler(Activator.class); + + private static BundleContext context; + + private StatsJob statsJob = new StatsJob( + "Collaboration Network Statistics", + com.raytheon.uf.viz.collaboration.comm.Activator.getDefault() + .getNetworkStats()); + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext + * ) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + statsJob.schedule(); + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + statsJob.shutdown(); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/IRemoteDisplayContainer.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/IRemoteDisplayContainer.java new file mode 100644 index 0000000000..9accc6236a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/IRemoteDisplayContainer.java @@ -0,0 +1,95 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display; + +import org.eclipse.ui.IEditorPart; + +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; + +/** + * Interface for object that contains remote displays + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 12, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface IRemoteDisplayContainer { + + public static class RemoteDisplay { + private final int displayId; + + private final IRenderableDisplay display; + + /** + * @param displayId + * @param display + */ + public RemoteDisplay(int displayId, IRenderableDisplay display) { + this.displayId = displayId; + this.display = display; + } + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @return the display + */ + public IRenderableDisplay getDisplay() { + return display; + } + + } + + public static enum RemoteDisplayChangeType { + CREATED, DISPOSED, ACTIVATED; + } + + public static interface IRemoteDisplayChangedListener { + public void remoteDisplayChanged(RemoteDisplay remoteDisplay, + RemoteDisplayChangeType changeType); + } + + public void addRemoteDisplayChangedListener( + IRemoteDisplayChangedListener listener); + + public void removeRemoteDisplayChangedListener( + IRemoteDisplayChangedListener listener); + + public RemoteDisplay getActiveDisplay(); + + public IEditorPart getActiveDisplayEditor(); + + public void disposeContainer(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/ColorChangeEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/ColorChangeEvent.java new file mode 100644 index 0000000000..f3809f7681 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/ColorChangeEvent.java @@ -0,0 +1,153 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.data; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * Event for when a new user enters and a color is added + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 11, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class ColorChangeEvent { + @DynamicSerializeElement + private UserId userName; + + @DynamicSerializeElement + private Integer red; + + @DynamicSerializeElement + private Integer green; + + @DynamicSerializeElement + private Integer blue; + + public ColorChangeEvent() { + } + + public ColorChangeEvent(UserId user, RGB color) { + this.userName = user; + if (color != null) { + red = color.red; + green = color.green; + blue = color.blue; + } + } + + /** + * @param userName + * the userName to set + */ + public void setUserName(UserId userName) { + this.userName = userName; + } + + /** + * @return the userName + */ + public UserId getUserName() { + return userName; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + if (color != null) { + red = color.red; + green = color.green; + blue = color.blue; + } + } + + /** + * @return the color + */ + public RGB getColor() { + RGB color = null; + if (red != null && green != null && blue != null) { + color = new RGB(red, green, blue); + } + return color; + } + + /** + * @return the red + */ + public Integer getRed() { + return red; + } + + /** + * @param red + * the red to set + */ + public void setRed(Integer red) { + this.red = red; + } + + /** + * @return the green + */ + public Integer getGreen() { + return green; + } + + /** + * @param green + * the green to set + */ + public void setGreen(Integer green) { + this.green = green; + } + + /** + * @return the blue + */ + public Integer getBlue() { + return blue; + } + + /** + * @param blue + * the blue to set + */ + public void setBlue(Integer blue) { + this.blue = blue; + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SessionColorManager.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SessionColorManager.java new file mode 100644 index 0000000000..7b7ec4b08c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SessionColorManager.java @@ -0,0 +1,102 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.data; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.viz.core.ColorUtil; + +/** + * + * Manages colors of different users for a session + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 3, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class SessionColorManager { + + private Map colors; + + private static RGB[] rgbPresets = null; + + /** + * + */ + public SessionColorManager() { + if (colors == null) { + colors = new HashMap(); + rgbPresets = ColorUtil.getResourceColorPresets(); + } + } + + /** + * @return the colors + */ + public Map getColors() { + return colors; + } + + public void setColors(Map map) { + colors = map; + } + + public RGB getColorFromUser(UserId user) { + if (colors.get(user) == null) { + addUser(user); + } + return colors.get(user); + } + + public void setColorForUser(UserId id, RGB rgb) { + colors.put(id, rgb); + } + + /** + * Add a user with a new color value + * + * @param user + */ + public void addUser(UserId user) { + int count = colors.size(); + if (rgbPresets.length <= count) { + count = count % rgbPresets.length; + } + colors.put(user, rgbPresets[count]); + } + + public void clearColors() { + colors.clear(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SessionContainer.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SessionContainer.java new file mode 100644 index 0000000000..479d16b7ba --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SessionContainer.java @@ -0,0 +1,115 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.data; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer; +import com.raytheon.uf.viz.collaboration.display.roles.IRoleEventController; + +/** + * A container holding an underlying session and associated data for a shared + * display session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class SessionContainer { + + /** the session id **/ + private String sessionId; + + /** the underlying session object **/ + private ISharedDisplaySession session; + + /** subscribes to events related to the session based on role **/ + private IRoleEventController roleEventController; + + private SessionColorManager colorManager; + + private IRemoteDisplayContainer displayContainer; + + public ISharedDisplaySession getSession() { + return session; + } + + public void setSession(ISharedDisplaySession session) { + this.session = session; + } + + public IRoleEventController getRoleEventController() { + return roleEventController; + } + + public void setRoleEventController(IRoleEventController roleEventController) { + this.roleEventController = roleEventController; + } + + /** + * @return the displayContainer + */ + public IRemoteDisplayContainer getDisplayContainer() { + return displayContainer; + } + + /** + * @param displayContainer + * the displayContainer to set + */ + public void setDisplayContainer(IRemoteDisplayContainer displayContainer) { + this.displayContainer = displayContainer; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + /** + * @return the colorManager + */ + public SessionColorManager getColorManager() { + if (colorManager == null) { + colorManager = new SessionColorManager(); + } + return colorManager; + } + + /** + * @param colorManager + * the colorManager to set + */ + public void setColorManager(SessionColorManager colorManager) { + this.colorManager = colorManager; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SharedDisplaySessionMgr.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SharedDisplaySessionMgr.java new file mode 100644 index 0000000000..1f5ea8d8f2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/data/SharedDisplaySessionMgr.java @@ -0,0 +1,107 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.data; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.eclipse.ui.IEditorPart; + +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.display.roles.DataProviderEventController; +import com.raytheon.uf.viz.collaboration.display.roles.IRoleEventController; +import com.raytheon.uf.viz.collaboration.display.roles.ParticipantEventController; + +/** + * Tracks all of the active sessions that are SharedDisplaySessions. Provides + * SessionContainers that contain the data related to those sessions. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class SharedDisplaySessionMgr { + + private static Map sharedDisplaySessionMap = new HashMap(); + + public static SessionContainer getSessionContainer(String sessionId) { + return sharedDisplaySessionMap.get(sessionId); + } + + public static Set getActiveSessionIds() { + return sharedDisplaySessionMap.keySet(); + } + + public static void joinSession(ISharedDisplaySession session, + SharedDisplayRole initialRole, SessionColorManager colors) + throws CollaborationException { + SessionContainer container = new SessionContainer(); + container.setSessionId(session.getSessionId()); + container.setSession(session); + + IRoleEventController rec = null; + switch (initialRole) { + case DATA_PROVIDER: + rec = new DataProviderEventController(session); + break; + case PARTICIPANT: + rec = new ParticipantEventController(session); + break; + default: + throw new IllegalArgumentException( + "ParticipantRole must be DataProvider or Participant for initialization"); + } + container.setRoleEventController(rec); + if (colors != null) { + container.setColorManager(colors); + } + sharedDisplaySessionMap.put(session.getSessionId(), container); + + rec.startup(); + } + + /** + * Removes a session from the manager. + * + * @param sessionId + */ + public static void exitSession(String sessionId) { + SessionContainer container = sharedDisplaySessionMap.get(sessionId); + if (container != null) { + container.getRoleEventController().shutdown(); + + // remove after shutting down event controller + sharedDisplaySessionMap.remove(sessionId); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ActivateRemoteDisplay.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ActivateRemoteDisplay.java new file mode 100644 index 0000000000..43e5536157 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ActivateRemoteDisplay.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Event for activating a remote display + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ActivateRemoteDisplay { + + @DynamicSerializeElement + private int displayId; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/CollaborationEditorInput.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/CollaborationEditorInput.java new file mode 100644 index 0000000000..1ff5bc246f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/CollaborationEditorInput.java @@ -0,0 +1,121 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IPersistableElement; + +/** + * Editor input for CollaborationEditor + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 7, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationEditorInput implements IEditorInput { + + private String title; + + private String sessionId; + + public CollaborationEditorInput(String sessionId, String title) { + this.sessionId = sessionId; + this.title = title; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return sessionId; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + @Override + public Object getAdapter(Class adapter) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#exists() + */ + @Override + public boolean exists() { + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#getImageDescriptor() + */ + @Override + public ImageDescriptor getImageDescriptor() { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#getName() + */ + @Override + public String getName() { + return title; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#getPersistable() + */ + @Override + public IPersistableElement getPersistable() { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.IEditorInput#getToolTipText() + */ + @Override + public String getToolTipText() { + return getName(); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/CreateRemoteDisplay.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/CreateRemoteDisplay.java new file mode 100644 index 0000000000..5e664237f3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/CreateRemoteDisplay.java @@ -0,0 +1,90 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; + +/** + * A SharedEditorData is a POJO to be sent out by the Data Provider that + * contains enough information to create the CollaborationEditor for the + * participants. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class CreateRemoteDisplay implements ISerializableObject { + + @XmlAttribute + private int displayId; + + @XmlElement + private AbstractRenderableDisplay display; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the display + */ + public AbstractRenderableDisplay getDisplay() { + return display; + } + + /** + * @param display + * the display to set + */ + public void setDisplay(AbstractRenderableDisplay display) { + this.display = display; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/DisposeRemoteDisplay.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/DisposeRemoteDisplay.java new file mode 100644 index 0000000000..4a1851423a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/DisposeRemoteDisplay.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Event object for disposes a remote display + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DisposeRemoteDisplay { + + @DynamicSerializeElement + private int displayId; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ICollaborationEditor.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ICollaborationEditor.java new file mode 100644 index 0000000000..79c49edd9f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ICollaborationEditor.java @@ -0,0 +1,56 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.ui.IEditorPart; + +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer; +import com.raytheon.uf.viz.core.IDisplayPane; + +/** + * Interface for the Collaboration Editor + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface ICollaborationEditor extends IEditorPart, + IRemoteDisplayContainer { + + public static final String EDITOR_ID = "com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor"; + + public IDisplayPane getActiveDisplayPane(); + + public void setCanvasBounds(int displayId, Rectangle canvasBounds); + + public String getSessionId(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/RemoteDisplayRequested.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/RemoteDisplayRequested.java new file mode 100644 index 0000000000..c07f33102c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/RemoteDisplayRequested.java @@ -0,0 +1,80 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Requests a remote display object be sent to the user + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class RemoteDisplayRequested { + + @DynamicSerializeElement + private int displayId; + + @DynamicSerializeElement + private String userId; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the userId + */ + public String getUserId() { + return userId; + } + + /** + * @param userId + * the userId to set + */ + public void setUserId(String userId) { + this.userId = userId; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ReprojectRemoteDisplay.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ReprojectRemoteDisplay.java new file mode 100644 index 0000000000..5e16bc85d5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/editor/ReprojectRemoteDisplay.java @@ -0,0 +1,82 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.editor; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Collaboration event to reproject the viewing editor + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ReprojectRemoteDisplay { + + @DynamicSerializeElement + private int displayId; + + @DynamicSerializeElement + private GeneralGridGeometry targetGeometry; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the targetGeometry + */ + public GeneralGridGeometry getTargetGeometry() { + return targetGeometry; + } + + /** + * @param targetGeometry + * the targetGeometry to set + */ + public void setTargetGeometry(GeneralGridGeometry targetGeometry) { + this.targetGeometry = targetGeometry; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/AbstractRoleEventController.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/AbstractRoleEventController.java new file mode 100644 index 0000000000..bc63d528f8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/AbstractRoleEventController.java @@ -0,0 +1,73 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer; +import com.raytheon.uf.viz.collaboration.display.data.SessionContainer; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; + +/** + * Abstract role event controller that shares fields and methods that are common + * to other event controllers. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public abstract class AbstractRoleEventController + implements IRoleEventController { + + protected ISharedDisplaySession session; + + protected T container; + + protected AbstractRoleEventController(ISharedDisplaySession session) { + this.session = session; + } + + @Override + public void startup() { + session.registerEventHandler(this); + SessionContainer sc = SharedDisplaySessionMgr + .getSessionContainer(session.getSessionId()); + container = createDisplayContainer(); + sc.setDisplayContainer(container); + } + + @Override + public void shutdown() { + session.unregisterEventHandler(this); + container.disposeContainer(); + } + + protected abstract T createDisplayContainer(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/DataProviderEventController.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/DataProviderEventController.java new file mode 100644 index 0000000000..039560dc94 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/DataProviderEventController.java @@ -0,0 +1,142 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles; + +import org.eclipse.swt.graphics.RGB; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.ColorPopulator; +import com.raytheon.uf.viz.collaboration.display.data.ColorChangeEvent; +import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.editor.ActivateRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * TODO: This class is in severe need of a refactor! + * + * Handles the events of a session that are specific to the Data Provider role. + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class DataProviderEventController extends + AbstractRoleEventController { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(DataProviderEventController.class); + + public DataProviderEventController(ISharedDisplaySession session) { + super(session); + } + + @Subscribe + public void participantChanged(IVenueParticipantEvent event) { + if (event.getEventType().equals(ParticipantEventType.ARRIVED) + && !event.getParticipant().equals(session.getUserID())) { + try { + AbstractEditor active = container.getActiveSharedEditor(); + if (active != null) { + IDisplayPane activePane = active.getActiveDisplayPane(); + if (activePane != null) { + ActivateRemoteDisplay arde = new ActivateRemoteDisplay(); + arde.setDisplayId(container.getDisplayId(activePane + .getRenderableDisplay())); + session.sendObjectToPeer(event.getParticipant(), arde); + } + } + + // new color for each user + SessionColorManager scm = SharedDisplaySessionMgr + .getSessionContainer(session.getSessionId()) + .getColorManager(); + RGB color = scm.getColorFromUser(event.getParticipant()); + + ColorChangeEvent cce = new ColorChangeEvent( + event.getParticipant(), color); + session.sendObjectToPeer(event.getParticipant(), + new ColorPopulator(scm.getColors())); + session.sendObjectToVenue(cce); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error sending initialization data to new participant " + + event.getParticipant().getName(), e); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.AbstractRoleEventController + * #startup() + */ + @Override + public void startup() { + super.startup(); + AbstractEditor active = EditorUtil + .getActiveEditorAs(AbstractEditor.class); + if (active != null + && SharedEditorsManager.isBeingShared(active) == false) { + try { + container.shareEditor(active); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.display.roles.AbstractRoleEventController + * #createDisplayContainer() + */ + @Override + protected SharedEditorsManager createDisplayContainer() { + return SharedEditorsManager.getManager(session); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/IRoleEventController.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/IRoleEventController.java new file mode 100644 index 0000000000..51acfea11a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/IRoleEventController.java @@ -0,0 +1,46 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles; + +/** + * Interface for an event controller. Starting up an IRoleEventController is + * akin to subscribing to events specific to that specific role. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public interface IRoleEventController { + + public void startup(); + + public void shutdown(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/ParticipantEventController.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/ParticipantEventController.java new file mode 100644 index 0000000000..849bf891d9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/ParticipantEventController.java @@ -0,0 +1,73 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles; + +import org.eclipse.ui.PartInitException; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.editor.CollaborationEditorInput; +import com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor; +import com.raytheon.viz.ui.VizWorkbenchManager; + +/** + * Handles the events of a session that are specific to the Participant role. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class ParticipantEventController extends + AbstractRoleEventController { + + public ParticipantEventController(ISharedDisplaySession session) { + super(session); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.display.roles.AbstractRoleEventController + * #createDisplayContainer() + */ + @Override + protected ICollaborationEditor createDisplayContainer() { + CollaborationEditorInput input = new CollaborationEditorInput( + session.getSessionId(), session.getVenue().getInfo() + .getVenueDescription()); + try { + return (ICollaborationEditor) VizWorkbenchManager.getInstance() + .getCurrentWindow().getActivePage() + .openEditor(input, ICollaborationEditor.EDITOR_ID); + } catch (PartInitException e) { + throw new RuntimeException("Error opening collaboration editor", e); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/CollaborationDispatcher.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/CollaborationDispatcher.java new file mode 100644 index 0000000000..f568b70a2e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/CollaborationDispatcher.java @@ -0,0 +1,333 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider; + +import java.util.ArrayDeque; +import java.util.Arrays; +import java.util.Deque; + +import org.eclipse.swt.widgets.Event; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.compression.CompressionUtil; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.IRenderFrameEvent; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.MouseLocationEvent; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.RenderFrame; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.RenderFrameNeededEvent; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ParticipantInitializedEvent; +import com.raytheon.uf.viz.collaboration.display.storage.CollaborationObjectEventStorage; +import com.raytheon.uf.viz.collaboration.display.storage.IObjectEventPersistance; +import com.raytheon.uf.viz.collaboration.display.storage.IPersistedEvent; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.jobs.JobPool; +import com.raytheon.uf.viz.core.rsc.IInputHandler; +import com.raytheon.uf.viz.remote.graphics.Dispatcher; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.AbstractRemoteGraphicsEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.BeginFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.EndFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; +import com.raytheon.viz.ui.input.InputAdapter; + +/** + * Dispatches graphics objects to participants in the collaboration session + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 19, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationDispatcher extends Dispatcher { + + private static JobPool persistPool = new JobPool("Persister", 1, true); + + private static final int IMMEDIATE_SEND_SIZE = 1024; + + private static final int MAX_PREV_FRAMES = 10; + + private ISharedDisplaySession session; + + private IObjectEventPersistance persistance; + + private Deque previousFrames = new ArrayDeque(); + + private RenderFrame currentFrame; + + private IInputHandler mouseCapturer = new InputAdapter() { + + private double[] mouseLocation; + + @Override + public boolean handleMouseMove(int x, int y) { + IDisplayPaneContainer container = display.getContainer(); + for (IDisplayPane pane : container.getDisplayPanes()) { + if (pane.getRenderableDisplay() == display) { + update(display.screenToGrid(x, y, 1.0, pane.getTarget())); + break; + } + } + return false; + } + + @Override + public boolean handleMouseExit(Event event) { + update(null); + return false; + } + + @Override + public boolean handleMouseEnter(Event event) { + handleMouseMove(event.x, event.y); + return false; + } + + private void update(double[] mouseLocation) { + if (!Arrays.equals(mouseLocation, this.mouseLocation)) { + this.mouseLocation = mouseLocation; + MouseLocationEvent event = new MouseLocationEvent(); + event.setDisplayId(getDispatcherId()); + event.setMouseLocation(mouseLocation); + send(event); + } + } + }; + + private IRenderableDisplay display; + + private IRenderableDisplay activeDisplay; + + private boolean disposed = false; + + public CollaborationDispatcher(ISharedDisplaySession session, + IRenderableDisplay display) throws CollaborationException { + this.session = session; + this.display = display; + this.persistance = CollaborationObjectEventStorage + .createPersistanceObject(session, this); + session.registerEventHandler(this); + // TODO: + // Not sure if we should show mouse location or not due to + // bandwidth, messages are very small but frequent + // display.getContainer().registerMouseHandler(mouseCapturer); + } + + /** + * Update the active display to render for + * + * @param display + */ + public void setActiveDisplay(IRenderableDisplay active) { + if (display != active) { + disposeFrames(); + } + this.activeDisplay = active; + display.refresh(); + } + + @Subscribe + public void handleNeedsRenderFrameEvent(RenderFrameNeededEvent event) { + synchronized (previousFrames) { + RenderFrame needed = null; + for (RenderFrame prevFrame : previousFrames) { + if (prevFrame.getObjectId() == event.getObjectId()) { + needed = prevFrame; + } + } + if (needed != null) { + // Remove and dispose to reset frame + previousFrames.remove(needed); + needed.dispose(); + display.refresh(); + } + } + } + + @Subscribe + public void handleParticipantInitialized(ParticipantInitializedEvent event) { + // Force repaint when participant initializes + display.refresh(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.Dispatcher#dispatch(com.raytheon. + * uf.viz.remote.graphics.AbstractRemoteGraphicsEvent) + */ + @Override + public void dispatch(AbstractRemoteGraphicsEvent eventObject) { + if (eventObject instanceof IRenderFrameEvent) { + if (activeDisplay == display) { + // Only dispatch render frame events IF we are active + send(eventObject); + } + return; + } + // Set PERSISTENCE to true if testing persisting capabilities + if (eventObject instanceof AbstractDispatchingObjectEvent + && eventObject instanceof IRenderEvent == false) { + boolean immediateSend = true; + if (eventObject instanceof ICreationEvent == false) { + // Not a creation event, check event size. All creation events + // are sent immediately to avoid false negatives + try { + byte[] data = CompressionUtil.compress(SerializationUtil + .transformToThrift(eventObject)); + if (data.length > IMMEDIATE_SEND_SIZE) { + immediateSend = false; + } + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error determing size of eventObject: " + + eventObject, e); + } + } + final AbstractDispatchingObjectEvent toPersist = (AbstractDispatchingObjectEvent) eventObject; + final boolean[] sendPersisted = new boolean[] { !immediateSend }; + persistPool.schedule(new Runnable() { + @Override + public void run() { + try { + synchronized (persistance) { + if (!disposed) { + IPersistedEvent event = persistance + .persistEvent(toPersist); + // If was no immediateSend, send now + if (sendPersisted[0]) { + send(event); + } + } + } + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + }); + // Need to immediately send eventObject + if (immediateSend) { + send(eventObject); + } + } else if (eventObject instanceof IRenderEvent) { + if (eventObject instanceof BeginFrameEvent && currentFrame == null) { + currentFrame = new RenderFrame(this); + } + + currentFrame.addEvent((IRenderEvent) eventObject); + if (eventObject instanceof EndFrameEvent) { + synchronized (previousFrames) { + // End frame, do some smart rendering + RenderFrame mergeWith = null; + for (RenderFrame prevFrame : previousFrames) { + // Try and find a previous frame with same number of + // frames + if (prevFrame.size() == currentFrame.size()) { + mergeWith = prevFrame; + break; + } + } + + boolean merged = false; + if (mergeWith != null) { + // Move merge frame to front of queue + previousFrames.remove(mergeWith); + previousFrames.addFirst(mergeWith); + + if (mergeWith.merge(currentFrame)) { + // Mark successfull merge + merged = true; + // Reset current frame + currentFrame.clear(); + } + } + + if (!merged) { + // Send full frame if no merge happened + if (mergeWith != null) { + // Notify we tried to merge but failed + Activator.statusHandler.handle(Priority.PROBLEM, + "Attempted merge did not succeed"); + } + + // Send current frame + currentFrame.sendFrame(); + if (previousFrames.size() == MAX_PREV_FRAMES) { + // Too many frames, remove and dispose last + previousFrames.removeLast().dispose(); + } + previousFrames.addFirst(currentFrame); + currentFrame = new RenderFrame(this); + } + } + } + } else { + Activator.statusHandler.handle(Priority.PROBLEM, + "Unable to handle event type: " + eventObject); + } + } + + private void send(Object obj) { + try { + session.sendObjectToVenue(obj); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + public void dispose() { + disposed = true; + try { + synchronized (persistance) { + persistance.dispose(); + } + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + disposeFrames(); + session.unregisterEventHandler(this); + } + + private void disposeFrames() { + for (RenderFrame frame : previousFrames) { + frame.dispose(); + } + previousFrames.clear(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/ISharedEditorsManagerListener.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/ISharedEditorsManagerListener.java new file mode 100644 index 0000000000..0143b283ed --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/ISharedEditorsManagerListener.java @@ -0,0 +1,46 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider; + +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Listener for SharedEditorsManager events. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 6, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ +public interface ISharedEditorsManagerListener { + + public void removeEditor(AbstractEditor editor); + + public void shareEditor(AbstractEditor editor); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/SharedEditorsManager.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/SharedEditorsManager.java new file mode 100644 index 0000000000..ca4bcdc6d9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/SharedEditorsManager.java @@ -0,0 +1,934 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer; +import com.raytheon.uf.viz.collaboration.display.editor.ActivateRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.CreateRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.DisposeRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.RemoteDisplayRequested; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.rsc.DataProviderRscData; +import com.raytheon.uf.viz.collaboration.display.rsc.CollaborationWrapperResource; +import com.raytheon.uf.viz.collaboration.display.rsc.CollaborationWrapperResourceData; +import com.raytheon.uf.viz.collaboration.display.rsc.SelfAddingSystemResourceListener; +import com.raytheon.uf.viz.collaboration.display.rsc.event.SharedResource; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IRenderableDisplayChangedListener; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.ResourceList.AddListener; +import com.raytheon.uf.viz.remote.graphics.Dispatcher; +import com.raytheon.uf.viz.remote.graphics.DispatcherFactory; +import com.raytheon.uf.viz.remote.graphics.DispatchingGraphicsFactory; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Manager class for managing the sharing of editors in an + * {@link ISharedDisplaySession} + * + * TODO: Handle DataProviderRsc adding/removing! Maybe put in wrap/unwrap + * resource? + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class SharedEditorsManager implements IRemoteDisplayContainer { + + public class RemoteDisplayEventHandler { + @Subscribe + public void remoteDisplayRequested(RemoteDisplayRequested event) { + String userId = event.getUserId(); + UserId user = null; + for (UserId uid : session.getVenue().getParticipants()) { + if (uid.getFQName().equals(userId)) { + user = uid; + break; + } + } + if (user != null) { + int displayId = event.getDisplayId(); + RemoteDisplay requested = null; + for (DisplayData data : displayData.values()) { + if (data.displayId == displayId) { + requested = new RemoteDisplay(data.displayId, + data.display); + break; + } + } + if (requested == null) { + requested = getActiveDisplay(); + if (requested != null) { + ActivateRemoteDisplay activate = new ActivateRemoteDisplay(); + activate.setDisplayId(requested.getDisplayId()); + sendEvent(activate); + } + } else { + CreateRemoteDisplay creation = new CreateRemoteDisplay(); + creation.setDisplayId(requested.getDisplayId()); + creation.setDisplay(createRemoteDisplay(requested + .getDisplay())); + sendEvent(creation); + } + } + } + } + + private class SharedEditorDisplayChangedListener implements + IRenderableDisplayChangedListener { + + private AbstractEditor sharedEditor; + + private SharedEditorDisplayChangedListener(AbstractEditor sharedEditor) { + this.sharedEditor = sharedEditor; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IRenderableDisplayChangedListener# + * renderableDisplayChanged(com.raytheon.uf.viz.core.IDisplayPane, + * com.raytheon.uf.viz.core.drawables.IRenderableDisplay, + * com.raytheon.uf + * .viz.core.IRenderableDisplayChangedListener.DisplayChangeType) + */ + @Override + public void renderableDisplayChanged(IDisplayPane pane, + IRenderableDisplay newRenderableDisplay, DisplayChangeType type) { + if (type == DisplayChangeType.ADD) { + try { + if (displayData.containsKey(newRenderableDisplay) == false) { + // We aren't sharing this display, but is anyone else? + if (isBeingShared(newRenderableDisplay)) { + // if so, remove it from their session + removeDisplay(pane); + } + shareDisplay(pane); + } + if (activeSharedEditor == sharedEditor) { + activeSharedEditor = null; + activateEditor(sharedEditor); + } + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + } + + private class UnsharedEditorDisplayChangedListener implements + IRenderableDisplayChangedListener { + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.IRenderableDisplayChangedListener# + * renderableDisplayChanged(com.raytheon.uf.viz.core.IDisplayPane, + * com.raytheon.uf.viz.core.drawables.IRenderableDisplay, + * com.raytheon.uf + * .viz.core.IRenderableDisplayChangedListener.DisplayChangeType) + */ + @Override + public void renderableDisplayChanged(IDisplayPane pane, + IRenderableDisplay newRenderableDisplay, DisplayChangeType type) { + // An unshared editor had the renderable display changed, check if + // newRenderableDisplay is being shared by a manager + if (type == DisplayChangeType.ADD + && displayData.containsKey(newRenderableDisplay)) { + AbstractEditor editor = (AbstractEditor) newRenderableDisplay + .getContainer(); + if (allSharedEditors.contains(editor) == false) { + try { + shareEditor(editor); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + } + + } + + private class SharedEditorPartListener implements IPartListener { + + private List pages = new LinkedList(); + + private void addPage(IWorkbenchPage page) { + if (pages.contains(page) == false) { + for (IEditorReference ref : page.getEditorReferences()) { + partOpened(ref.getEditor(false)); + } + page.addPartListener(this); + pages.add(page); + } + } + + private void removePage(IWorkbenchPage page) { + if (pages.contains(page)) { + // We are listening on this page, should we be? + for (AbstractEditor editor : sharedEditors) { + if (editor.getSite().getPage() == page) { + // Another shared editor is on this page, keep listening + return; + } + } + // Made it here, we should not be listening anymore + page.removePartListener(this); + pages.remove(page); + } + } + + @Override + public void partActivated(IWorkbenchPart part) { + if (sharedEditors.contains(part)) { + activateEditor((AbstractEditor) part); + } else if (part instanceof IEditorPart) { + deactivateEditors(); + } + } + + @Override + public void partClosed(IWorkbenchPart part) { + if (sharedEditors.contains(part)) { + try { + removeEditor((AbstractEditor) part); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + + } + + @Override + public void partOpened(IWorkbenchPart part) { + if (part instanceof AbstractEditor) { + AbstractEditor editor = (AbstractEditor) part; + editor.addRenderableDisplayChangedListener(unsharedEditorListener); + } + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + if (activeSharedEditor == null && sharedEditors.contains(part)) { + activateEditor((AbstractEditor) part); + } + } + } + + private class SharedEditorDispatcherFactory implements DispatcherFactory { + @Override + public Dispatcher createNewDispatcher(IRenderableDisplay display) + throws InstantiationException { + try { + CollaborationDispatcher dispatcher = new CollaborationDispatcher( + session, display); + DisplayData data = new DisplayData(); + data.display = display; + data.dispatcher = dispatcher; + data.displayId = dispatcher.getDispatcherId(); + data.resourceListener = new SharedEditorResourceWrapperListener( + display, data.displayId); + displayData.put(display, data); + return dispatcher; + } catch (Exception e) { + InstantiationException ie = new InstantiationException( + "Error creating new dispatcher: " + + e.getLocalizedMessage()); + ie.initCause(e); + throw ie; + } + } + } + + private class SharedEditorResourceWrapperListener extends + SelfAddingSystemResourceListener implements AddListener { + + private int displayId; + + private SharedEditorResourceWrapperListener(IRenderableDisplay display, + int displayId) throws VizException { + super(new DataProviderRscData(session.getSessionId(), displayId), + display.getDescriptor()); + this.displayId = displayId; + this.descriptor.getResourceList().addPostAddListener(this); + } + + @Override + public void notifyAdd(ResourcePair rp) throws VizException { + wrapResourcePair(rp); + if (shouldBeLocal(rp)) { + sendSharedResource(displayId, rp, false); + } + } + + @Override + public void notifyRemove(ResourcePair rp) throws VizException { + super.notifyRemove(rp); + if (rp.getResource() instanceof CollaborationWrapperResource) { + // Send event to venue to unload + sendSharedResource(displayId, rp, true); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.rsc. + * SelfAddingSystemResourceListener#dispose() + */ + @Override + public void dispose() { + super.dispose(); + this.descriptor.getResourceList().removePostAddListener(this); + } + + } + + private static class DisplayData { + private SharedEditorResourceWrapperListener resourceListener; + + private CollaborationDispatcher dispatcher; + + private IRenderableDisplay display; + + private int displayId; + } + + private static Map managerMap = new HashMap(); + + private static List allSharedEditors = new LinkedList(); + + /** + * Gets/Creates the SharedEditorManager for the given session + * + * @param session + * @return + */ + public static SharedEditorsManager getManager(ISharedDisplaySession session) { + SharedEditorsManager manager = managerMap.get(session.getSessionId()); + if (manager == null) { + manager = new SharedEditorsManager(session); + managerMap.put(session.getSessionId(), manager); + } + return manager; + } + + /** + * + * @param editor + * @return + */ + public static ISharedDisplaySession getSharedEditorSession( + AbstractEditor editor) { + for (String sessionId : managerMap.keySet()) { + SharedEditorsManager manager = managerMap.get(sessionId); + if (manager.sharedEditors.contains(editor)) { + return manager.session; + } + } + return null; + } + + /** + * Returns the shared display id for the renderable display. Returns -1 if + * display not shared + * + * @param display + * @return + */ + public static int getSharedDisplayId(IRenderableDisplay display) { + for (SharedEditorsManager manager : managerMap.values()) { + if (manager.displayData.containsKey(display)) { + return manager.displayData.get(display).displayId; + } + } + return -1; + } + + public static boolean isBeingShared(AbstractEditor editor) { + return allSharedEditors.contains(editor); + } + + public static boolean isBeingShared(IRenderableDisplay display) { + return getSharedDisplayId(display) != -1; + } + + private DispatcherFactory factory = new SharedEditorDispatcherFactory(); + + private SharedEditorPartListener partListener = new SharedEditorPartListener(); + + private Map listenerMap = new IdentityHashMap(); + + private List sharedEditors = new LinkedList(); + + private IRenderableDisplayChangedListener unsharedEditorListener = new UnsharedEditorDisplayChangedListener(); + + private Map displayData = new IdentityHashMap(); + + private Set listeners = new LinkedHashSet(); + + private SharedEditorsManagerListenerHandler sharedEditorsManagerListenerHandler = new SharedEditorsManagerListenerHandler(); + + private RemoteDisplayEventHandler eventHandler = new RemoteDisplayEventHandler(); + + private AbstractEditor activeSharedEditor; + + private String editorTitleSuffix; + + private ISharedDisplaySession session; + + private SharedEditorsManager(ISharedDisplaySession session) { + this.session = session; + session.registerEventHandler(eventHandler); + editorTitleSuffix = " (" + + session.getVenue().getInfo().getVenueDescription() + ")"; + } + + public int getDisplayId(IRenderableDisplay display) { + int displayId = -1; + DisplayData data = displayData.get(display); + if (data != null) { + displayId = data.displayId; + } + return displayId; + } + + public AbstractEditor getActiveSharedEditor() { + return activeSharedEditor; + } + + public List getSharedEditors() { + return new ArrayList(sharedEditors); + } + + /** + * Shares the AbstractEditor for the session. Throws exception if editor is + * already being shared + * + * @param editor + * @throws CollaborationException + */ + public void shareEditor(AbstractEditor editor) + throws CollaborationException { + if (sharedEditors.contains(editor) == false) { + if (allSharedEditors.contains(sharedEditors) == false) { + // Add to tracking lists + sharedEditors.add(editor); + allSharedEditors.add(editor); + + editor.removeRenderableDisplayChangedListener(unsharedEditorListener); + + try { + for (IDisplayPane pane : editor.getDisplayPanes()) { + shareDisplay(pane); + } + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error sharing editor: " + e.getLocalizedMessage(), + e); + removeEditor(editor); + return; + } + + // Add and manage display listener + SharedEditorDisplayChangedListener listener = new SharedEditorDisplayChangedListener( + editor); + editor.addRenderableDisplayChangedListener(listener); + listenerMap.put(editor, listener); + + // Update tab title + editor.setTabTitle(editor.getPartName() + editorTitleSuffix); + + partListener.addPage(editor.getSite().getPage()); + + // If editor is currently active, activate it! + if (EditorUtil.getActiveEditor(editor.getSite() + .getWorkbenchWindow()) == editor) { + activateEditor(editor); + } + sharedEditorsManagerListenerHandler.fireEditorShared(editor); + } else { + throw new CollaborationException( + "Cannot shared editor already being shared with another session"); + } + } else { + System.out.println("Unable to share editor!"); + Thread.dumpStack(); + throw new CollaborationException( + "Cannot share editor, it is already being shared with the session"); + } + } + + /** + * Removes the editor from being shared in the session. Throws exception if + * editor is not being shared by this session + * + * @param editor + * @throws CollaborationException + */ + public void removeEditor(AbstractEditor editor) + throws CollaborationException { + if (sharedEditors.contains(editor)) { + if (activeSharedEditor == editor) { + activeSharedEditor = null; + } + + // Remove renderable display listener + editor.removeRenderableDisplayChangedListener(listenerMap + .remove(editor)); + // Update tab title + String name = editor.getPartName(); + int endIndex = (name.length() < editorTitleSuffix.length()) ? name + .length() : name.length() - editorTitleSuffix.length(); + editor.setTabTitle(name.substring(0, endIndex)); + + sharedEditors.remove(editor); + partListener.removePage(editor.getSite().getPage()); + + for (IDisplayPane pane : editor.getDisplayPanes()) { + removeDisplay(pane); + } + + // This will trigger the editor to have the unshared editor listener + // added and support swapping in + partListener.partOpened(editor); + allSharedEditors.remove(editor); + + sharedEditorsManagerListenerHandler.fireEditorRemoved(editor); + } else { + throw new CollaborationException( + "Cannot unshare editor that isn't being shared by session"); + } + } + + @Override + public void disposeContainer() { + // Copy because remove will be called in the loop and we don't want + // concurrent modification. + List copy = new ArrayList(sharedEditors); + for (AbstractEditor editor : copy) { + try { + removeEditor(editor); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + // Clean up any dispatchers not removed from editors + // Copy because remove will be called in the loop and we don't want + // concurrent modification. + Collection data = new ArrayList( + this.displayData.values()); + for (DisplayData d : data) { + IRenderableDisplay display = d.display; + IDisplayPaneContainer container = display.getContainer(); + for (IDisplayPane pane : container.getDisplayPanes()) { + if (pane.getRenderableDisplay() == display) { + removeDisplay(pane); + break; + } + } + } + + session.unregisterEventHandler(eventHandler); + managerMap.remove(session.getSessionId()); + } + + /** + * Shares the display on the pane with the venue by creating a remote object + * representation for the participants, wrapping the local resources and + * injecting the remote target functionality. Should only be called if + * the display on the pane is not already being shared + * + * @param pane + * @throws CollaborationException + */ + private void shareDisplay(IDisplayPane pane) throws CollaborationException { + IRenderableDisplay display = pane.getRenderableDisplay(); + if (displayData.containsKey(display) == false + && display instanceof AbstractRenderableDisplay) { + // Clone the display + AbstractRenderableDisplay clonedDisplay = createRemoteDisplay(display); + if (clonedDisplay != null) { + wrapDisplay(display); + // Inject with remote target, have to find pane + try { + DispatchingGraphicsFactory.injectRemoteFunctionality(pane, + factory); + } catch (InstantiationException e) { + throw new CollaborationException( + "Error injecting remote functionality", e); + } + DisplayData data = displayData.get(display); + if (data != null) { + fireListeners(data, RemoteDisplayChangeType.CREATED); + CreateRemoteDisplay event = new CreateRemoteDisplay(); + event.setDisplayId(data.displayId); + event.setDisplay(clonedDisplay); + sendEvent(event); + } else { + throw new CollaborationException( + "Remote functionality injection failed"); + } + } + } + } + + /** + * Removes the shared display capability from the display pane + * + * @param pane + */ + private void removeDisplay(IDisplayPane pane) { + IRenderableDisplay display = pane.getRenderableDisplay(); + unwrapDisplay(display); + DispatchingGraphicsFactory.extractRemoteFunctionality(pane); + DisplayData data = displayData.remove(display); + if (data != null) { + fireListeners(data, RemoteDisplayChangeType.DISPOSED); + data.dispatcher.dispose(); + data.resourceListener.dispose(); + DisposeRemoteDisplay event = new DisposeRemoteDisplay(); + event.setDisplayId(data.displayId); + sendEvent(event); + } + } + + /** + * Creates a copy of the realDisplay object that can be used to send a + * {@link CreateRemoteDisplay} event. Does not matter if display is + * currently shared or not + * + * @param realDisplay + * @return + */ + private AbstractRenderableDisplay createRemoteDisplay( + IRenderableDisplay realDisplay) { + AbstractRenderableDisplay clonedDisplay = null; + if (realDisplay instanceof AbstractRenderableDisplay) { + clonedDisplay = ((AbstractRenderableDisplay) realDisplay) + .cloneDisplay(); + ResourceList clonedList = clonedDisplay.getDescriptor() + .getResourceList(); + clonedList.clear(); + List toKeep = new ArrayList(); + for (ResourcePair rp : realDisplay.getDescriptor() + .getResourceList()) { + if (shouldBeLocal(rp)) { + AbstractResourceData resourceData = rp.getResourceData(); + if (resourceData != null) { + if (resourceData instanceof CollaborationWrapperResourceData) { + resourceData = ((CollaborationWrapperResourceData) resourceData) + .getWrappedResourceData(); + } + + // Copy ResourcePair for our remote display + ResourcePair copy = new ResourcePair(); + copy.setLoadProperties(rp.getLoadProperties()); + copy.setProperties(rp.getProperties()); + copy.setResourceData(resourceData); + toKeep.add(copy); + } + } + } + clonedList.addAll(toKeep); + } + return clonedDisplay; + } + + /** + * Wraps the resources that will not be shared and drawn locally. + * + * @param display + */ + private void wrapDisplay(IRenderableDisplay display) { + ResourceList list = display.getDescriptor().getResourceList(); + for (ResourcePair rp : list) { + wrapResourcePair(rp); + } + } + + /** + * Unwraps the local wrapped resources from the display. + * + * @param display + */ + private void unwrapDisplay(IRenderableDisplay display) { + ResourceList list = display.getDescriptor().getResourceList(); + for (ResourcePair rp : list) { + unwrapResourcePair(rp); + } + } + + private boolean wrapResourcePair(ResourcePair rp) { + boolean wrapped = false; + if (shouldBeLocal(rp) + && rp.getResource() instanceof CollaborationWrapperResource == false + && rp.getResourceData() instanceof CollaborationWrapperResourceData == false) { + AbstractResourceData resourceData = rp.getResourceData(); + // Wrap resource data with wrapper object + CollaborationWrapperResourceData wrapperRscData = new CollaborationWrapperResourceData(); + wrapperRscData.setSession(session); + wrapperRscData.setWrappedResourceData(resourceData); + rp.setResourceData(wrapperRscData); + if (rp.getResource() != null) { + // If resource is set in pair, set here too + rp.setResource(new CollaborationWrapperResource(wrapperRscData, + rp.getLoadProperties(), rp.getResource())); + } + wrapped = true; + } + return wrapped; + } + + private boolean unwrapResourcePair(ResourcePair rp) { + boolean wasWrapped = false; + if (rp.getResourceData() instanceof CollaborationWrapperResourceData + || rp.getResource() instanceof CollaborationWrapperResource) { + if (rp.getResource() instanceof CollaborationWrapperResource) { + rp.setResource(((CollaborationWrapperResource) rp.getResource()) + .getWrappedResource()); + rp.setResourceData(rp.getResource().getResourceData()); + } else { + rp.setResourceData(((CollaborationWrapperResourceData) rp + .getResourceData()).getWrappedResourceData()); + } + wasWrapped = true; + } + return wasWrapped; + } + + /** + * Determines if the {@link ResourcePair} should be kept as a locally drawn + * resource or not + * + * @param rp + * @return + */ + private boolean shouldBeLocal(ResourcePair rp) { + return rp.getProperties().isMapLayer(); + } + + /** + * Sends an event to the venue marking the active display on the editor as + * the actively painting display + * + * @param editor + */ + private void activateEditor(AbstractEditor editor) { + if (activeSharedEditor != editor) { + activeSharedEditor = editor; + IDisplayPane pane = editor.getActiveDisplayPane(); + IRenderableDisplay display = pane.getRenderableDisplay(); + DisplayData data = displayData.get(display); + if (data != null) { + for (DisplayData d : displayData.values()) { + d.dispatcher.setActiveDisplay(display); + } + fireListeners(data, RemoteDisplayChangeType.ACTIVATED); + ActivateRemoteDisplay event = new ActivateRemoteDisplay(); + event.setDisplayId(data.displayId); + sendEvent(event); + } + } + } + + /** + * Sends an event to the venue indicating that no shared displaysa re + * currently active. + * + * @param editor + */ + private void deactivateEditors() { + if (activeSharedEditor != null) { + activeSharedEditor = null; + for (DisplayData d : displayData.values()) { + d.dispatcher.setActiveDisplay(null); + } + fireListeners(null, RemoteDisplayChangeType.ACTIVATED); + ActivateRemoteDisplay event = new ActivateRemoteDisplay(); + event.setDisplayId(-1); + sendEvent(event); + } + } + + /** + * Sends a shared resource event + * + * @param rp + * resource to send + * @param remove + * whether the resource should be added or removed by the + * participants + */ + private void sendSharedResource(int displayId, ResourcePair rp, + boolean remove) { + ResourcePair copy = new ResourcePair(); + copy.setLoadProperties(rp.getLoadProperties()); + copy.setProperties(rp.getProperties().clone()); + AbstractResourceData resourceData = rp.getResourceData(); + if (resourceData instanceof CollaborationWrapperResourceData) { + resourceData = ((CollaborationWrapperResourceData) resourceData) + .getWrappedResourceData(); + } else if (rp.getResource() instanceof CollaborationWrapperResource) { + copy.setResourceData(rp.getResource().getResourceData()); + } + copy.setResourceData(resourceData); + SharedResource resource = new SharedResource(); + resource.setDisplayId(displayId); + resource.setRemoveResource(remove); + resource.setResource(rp); + sendEvent(resource); + } + + /** + * Sends an object to the venue + * + * @param event + */ + private void sendEvent(Object event) { + try { + session.sendObjectToVenue(event); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + private void fireListeners(DisplayData data, RemoteDisplayChangeType type) { + RemoteDisplay rd = null; + if (data != null) { + rd = new RemoteDisplay(data.displayId, data.display); + } + for (IRemoteDisplayChangedListener listener : listeners) { + listener.remoteDisplayChanged(rd, type); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * addRemoteDisplayChangedListener + * (com.raytheon.uf.viz.collaboration.display. + * IRemoteDisplayContainer.IRemoteDisplayChangedListener) + */ + @Override + public void addRemoteDisplayChangedListener( + IRemoteDisplayChangedListener listener) { + listeners.add(listener); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * removeRemoteDisplayChangedListener + * (com.raytheon.uf.viz.collaboration.display + * .IRemoteDisplayContainer.IRemoteDisplayChangedListener) + */ + @Override + public void removeRemoteDisplayChangedListener( + IRemoteDisplayChangedListener listener) { + listeners.remove(listener); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * getActiveDisplay() + */ + @Override + public RemoteDisplay getActiveDisplay() { + if (activeSharedEditor == null) { + return null; + } + DisplayData data = displayData.get(activeSharedEditor + .getActiveDisplayPane().getRenderableDisplay()); + return new RemoteDisplay(data.displayId, data.display); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * getActiveDisplayEditor() + */ + @Override + public IEditorPart getActiveDisplayEditor() { + return activeSharedEditor; + } + + public void addListener(ISharedEditorsManagerListener listener) { + sharedEditorsManagerListenerHandler.addListener(listener); + } + + public void removeListener(ISharedEditorsManagerListener listener) { + sharedEditorsManagerListenerHandler.removeListener(listener); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/SharedEditorsManagerListenerHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/SharedEditorsManagerListenerHandler.java new file mode 100644 index 0000000000..1c35d1db34 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/SharedEditorsManagerListenerHandler.java @@ -0,0 +1,96 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider; + +import java.util.LinkedHashSet; +import java.util.Set; + +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Manages Listeners for SharedEditorsManager events. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 6, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ +public class SharedEditorsManagerListenerHandler { + + Set listeners = new LinkedHashSet(); + + /** + * Event for an editor unshared. + * + * @param editor + */ + public void fireEditorRemoved(AbstractEditor editor) { + ISharedEditorsManagerListener[] temp; + + synchronized (listeners) { + temp = listeners + .toArray(new ISharedEditorsManagerListener[listeners.size()]); + } + if (temp != null) { + for (ISharedEditorsManagerListener listener : temp) { + listener.removeEditor(editor); + } + } + } + + /** + * Event for an editor shared. + * + * @param editor + */ + public void fireEditorShared(AbstractEditor editor) { + ISharedEditorsManagerListener[] temp; + + synchronized (listeners) { + temp = listeners + .toArray(new ISharedEditorsManagerListener[listeners.size()]); + } + if (temp != null) { + for (ISharedEditorsManagerListener listener : temp) { + listener.shareEditor(editor); + } + } + } + + public void addListener(ISharedEditorsManagerListener listener) { + synchronized (listener) { + listeners.add(listener); + } + } + + public void removeListener(ISharedEditorsManagerListener listener) { + synchronized (listener) { + listeners.remove(listener); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/FrameDisposed.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/FrameDisposed.java new file mode 100644 index 0000000000..ce464b9040 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/FrameDisposed.java @@ -0,0 +1,45 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent; + +/** + * Special dispose event for RenderFrame objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class FrameDisposed extends DisposeObjectEvent implements + IRenderFrameEvent { + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/IRenderFrameEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/IRenderFrameEvent.java new file mode 100644 index 0000000000..0d24da5282 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/IRenderFrameEvent.java @@ -0,0 +1,42 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +/** + * Special interface for distinguishing IRenderFrameEvents from other render + * events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface IRenderFrameEvent { + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/MouseLocationEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/MouseLocationEvent.java new file mode 100644 index 0000000000..469585b402 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/MouseLocationEvent.java @@ -0,0 +1,98 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +import java.util.Arrays; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Collaboration mouse location event, contains mouse coordinates of data + * provider + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 2, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class MouseLocationEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private double[] mouseLocation; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.EndFrameEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + mouseLocation = ((MouseLocationEvent) diffEvent).mouseLocation; + } + + /** + * @return the mouseLocation + */ + public double[] getMouseLocation() { + return mouseLocation; + } + + /** + * @param mouseLocation + * the mouseLocation to set + */ + public void setMouseLocation(double[] mouseLocation) { + this.mouseLocation = mouseLocation; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MouseLocationEvent other = (MouseLocationEvent) obj; + if (!Arrays.equals(mouseLocation, other.mouseLocation)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrame.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrame.java new file mode 100644 index 0000000000..1b4c2f2f74 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrame.java @@ -0,0 +1,124 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import com.raytheon.uf.viz.remote.graphics.Dispatcher; +import com.raytheon.uf.viz.remote.graphics.DispatchingObject; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * RenderFrame object, tracks IRenderEvents and dispatches changes + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class RenderFrame extends DispatchingObject { + + private List renderEvents = new LinkedList(); + + /** + * @param targetObject + * @param dispatcher + */ + public RenderFrame(Dispatcher dispatcher) { + super(null, dispatcher); + } + + public void addEvent(IRenderEvent event) { + renderEvents.add(event); + } + + public boolean merge(RenderFrame existingFrame) { + if (existingFrame.renderEvents.size() != renderEvents.size()) { + return false; + } + + UpdateRenderFrameEvent updateEvent = RemoteGraphicsEventFactory + .createEvent(UpdateRenderFrameEvent.class, this); + Iterator myIter = renderEvents.iterator(); + Iterator newIter = existingFrame.renderEvents.iterator(); + boolean changes = false; + while (myIter.hasNext() && newIter.hasNext()) { + IRenderEvent myEvent = myIter.next(); + IRenderEvent newEvent = newIter.next(); + IRenderEvent update = null; + if (myEvent.getClass().equals(newEvent.getClass())) { + // Same type, check equality + if (myEvent.equals(newEvent) == false) { + // Not equal, create diff object + update = myEvent.createDiffObject(newEvent); + changes = true; + } + } else { + // Not compatible, full replace + update = newEvent; + changes = true; + } + updateEvent.addEvent(update); + } + + renderEvents.clear(); + renderEvents.addAll(existingFrame.renderEvents); + + if (changes == false) { + updateEvent.getRenderEvents().clear(); + } + // Send update event + dispatch(updateEvent); + return true; + } + + public void sendFrame() { + RenderFrameEvent event = RemoteGraphicsEventFactory.createEvent( + RenderFrameEvent.class, this); + event.setRenderEvents(new ArrayList(renderEvents)); + dispatch(event); + } + + public void dispose() { + dispatch(RemoteGraphicsEventFactory.createEvent(FrameDisposed.class, + this)); + } + + public void clear() { + renderEvents.clear(); + } + + public int size() { + return renderEvents.size(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrameEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrameEvent.java new file mode 100644 index 0000000000..21afce366d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrameEvent.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +import java.util.LinkedList; +import java.util.List; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for specifying a new RenderFrame object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 24, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class RenderFrameEvent extends AbstractDispatchingObjectEvent implements + IRenderFrameEvent { + + @DynamicSerializeElement + private List renderEvents = new LinkedList(); + + /** + * @return the renderEvents + */ + public List getRenderEvents() { + return renderEvents; + } + + /** + * @param renderEvents + * the renderEvents to set + */ + public void setRenderEvents(List renderEvents) { + this.renderEvents = renderEvents; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrameNeededEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrameNeededEvent.java new file mode 100644 index 0000000000..358ee0abad --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/RenderFrameNeededEvent.java @@ -0,0 +1,46 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Event for participants to tell the data provider they do not have a specific + * RenderFrame so the data provider will send it the next time it is painted + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 25, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class RenderFrameNeededEvent extends AbstractDispatchingObjectEvent + implements IRenderFrameEvent { + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/UpdateRenderFrameEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/UpdateRenderFrameEvent.java new file mode 100644 index 0000000000..dcf4e4faa3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/event/UpdateRenderFrameEvent.java @@ -0,0 +1,48 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event to update an existing RenderFrame + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 25, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateRenderFrameEvent extends RenderFrameEvent { + + public void addEvent(IRenderEvent event) { + getRenderEvents().add(event); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/rsc/DataProviderRsc.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/rsc/DataProviderRsc.java new file mode 100644 index 0000000000..138b856611 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/rsc/DataProviderRsc.java @@ -0,0 +1,172 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.rsc; + +import org.eclipse.swt.graphics.RGB; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager; +import com.raytheon.uf.viz.collaboration.display.data.SessionContainer; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.editor.ReprojectRemoteDisplay; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +import com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.remote.graphics.DispatchGraphicsTarget; + +/** + * A resource that is added to an editor that the Data Provider is sharing. It + * captures some events and also displays to the Data Provider that the editor + * is currently shared. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 13, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class DataProviderRsc extends + AbstractVizResource { + + private String roomName; + + private String subject; + + private ISharedDisplaySession session; + + private SessionColorManager colorManager; + + private IFont font; + + public DataProviderRsc(DataProviderRscData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + SessionContainer container = SharedDisplaySessionMgr + .getSessionContainer(resourceData.getSessionId()); + if (container != null) { + session = container.getSession(); + colorManager = container.getColorManager(); + IVenueInfo info = session.getVenue().getInfo(); + roomName = info.getVenueDescription(); + subject = info.getVenueSubject(); + } + } + + @Override + protected void disposeInternal() { + font.dispose(); + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + if (target instanceof DispatchGraphicsTarget) { + target = ((DispatchGraphicsTarget) target).getWrappedObject(); + } + target.clearClippingPlane(); + IExtent extent = paintProps.getView().getExtent(); + RGB color = colorManager.getColorFromUser(session.getUserID()); + target.drawRect(extent, color, 3.0f, 1.0f); + + DrawableString string = new DrawableString(getName(), color); + string.horizontalAlignment = HorizontalAlignment.CENTER; + string.verticallAlignment = VerticalAlignment.BOTTOM; + string.setCoordinates(extent.getMinX() + extent.getWidth() / 2, + extent.getMaxY()); + string.font = font; + string.textStyle = TextStyle.BLANKED; + target.drawStrings(string); + + target.setupClippingPlane(paintProps.getClippingPane()); + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + if (target instanceof DispatchGraphicsTarget) { + target = ((DispatchGraphicsTarget) target).getWrappedObject(); + } + font = target.getDefaultFont().deriveWithSize(11.0f); + font.setScaleFont(true); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#project(org.opengis. + * referencing.crs.CoordinateReferenceSystem) + */ + @Override + public void project(CoordinateReferenceSystem crs) throws VizException { + ReprojectRemoteDisplay event = new ReprojectRemoteDisplay(); + event.setTargetGeometry(descriptor.getGridGeometry()); + event.setDisplayId(resourceData.getDisplayId()); + try { + session.sendObjectToVenue(event); + } catch (CollaborationException e) { + Activator.statusHandler.handle( + Priority.PROBLEM, + "Error sending reprojection event: " + + e.getLocalizedMessage(), e); + } + } + + public String getName() { + String text = "Sharing with " + roomName; + if (subject.isEmpty() == false) { + text += " (" + subject + ")"; + } + return text; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#okToUnload() + */ + @Override + public boolean okToUnload() { + // Though I hate this methods exists, it serves its purpose + return false; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/rsc/DataProviderRscData.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/rsc/DataProviderRscData.java new file mode 100644 index 0000000000..fef1939fe1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/roles/dataprovider/rsc/DataProviderRscData.java @@ -0,0 +1,137 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.roles.dataprovider.rsc; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * Resource data for the dataprovider resource + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 25, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class DataProviderRscData extends AbstractResourceData { + + @XmlAttribute + private String sessionId; + + @XmlAttribute + private int displayId; + + public DataProviderRscData() { + + } + + public DataProviderRscData(String sessionId, int displayId) { + this.sessionId = sessionId; + this.displayId = displayId; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon + * .uf.viz.core.rsc.LoadProperties, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + @Override + public DataProviderRsc construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + return new DataProviderRsc(this, loadProperties); + } + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return sessionId; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object + * ) + */ + @Override + public void update(Object updateData) { + + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java new file mode 100644 index 0000000000..df925b1934 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResource.java @@ -0,0 +1,471 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.swt.graphics.Rectangle; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.FrameDisposed; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.IRenderFrameEvent; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.MouseLocationEvent; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.RenderFrameEvent; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.RenderFrameNeededEvent; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.UpdateRenderFrameEvent; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ParticipantInitializedEvent; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ReentrantEventHandler; +import com.raytheon.uf.viz.collaboration.display.rsc.rendering.CollaborationRenderingDataManager; +import com.raytheon.uf.viz.collaboration.display.rsc.rendering.CollaborationRenderingHandler; +import com.raytheon.uf.viz.collaboration.display.storage.IPersistedEvent; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.jobs.JobPool; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.AbstractRemoteGraphicsEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.BeginFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.EndFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; +import com.raytheon.viz.ui.cmenu.IContextMenuProvider; + +/** + * A resource for displaying rendered data that is received from the Data + * Provider. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 3, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class CollaborationResource extends + AbstractVizResource implements + IContextMenuProvider { + + private static JobPool retrievePool = new JobPool("Retriever", 1, true); + + private static class DisplayData { + /** List of objects rendered in paint */ + private List currentRenderables; + + /** Active list of renderable events to add to */ + private List activeRenderables; + + /** Queue of graphics data update events to process in paint */ + private List dataChangeEvents; + + /** Internal rendering event object router */ + private EventBus renderingRouter; + + private CollaborationRenderingDataManager dataManager; + + private MouseLocationEvent latestMouseLocation; + + private Set waitingOnObjects = new HashSet(); + + private Set waitingOnFrames = new HashSet(); + + private Map> renderableMap = new LinkedHashMap>() { + + private static final long serialVersionUID = 1L; + + /* + * (non-Javadoc) + * + * @see + * java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) + */ + @Override + protected boolean removeEldestEntry( + Entry> eldest) { + if (size() > 10) { + return true; + } + return false; + } + }; + + private DisplayData(int displayId, ISharedDisplaySession session, + CollaborationResource resource) { + dataChangeEvents = new LinkedList(); + currentRenderables = new LinkedList(); + activeRenderables = new LinkedList(); + renderingRouter = new ReentrantEventHandler(); + + dataManager = new CollaborationRenderingDataManager(session, + resource, displayId); + for (CollaborationRenderingHandler handler : CollaborationRenderingDataManager + .createRenderingHandlers(dataManager)) { + renderingRouter.register(handler); + } + } + + private void dispose() { + dataManager.dispose(); + renderingRouter = null; + } + } + + private Rectangle previousBounds = null; + + private DisplayData displayData; + + public CollaborationResource(CollaborationResourceData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + } + + @Override + protected void disposeInternal() { + resourceData.getSession().unregisterEventHandler(this); + displayData.dispose(); + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + if (displayData == null) { + return; + } + + Map> renderableMap = displayData.renderableMap; + List dataChangeEvents = displayData.dataChangeEvents; + Set waitingOnObjects = displayData.waitingOnObjects; + EventBus renderingRouter = displayData.renderingRouter; + + // Get the renderables for my extent + List currentRenderables = null; + synchronized (renderableMap) { + currentRenderables = renderableMap.get(paintProps.getView() + .getExtent()); + if (currentRenderables == null) { + synchronized (displayData.currentRenderables) { + currentRenderables = new ArrayList( + displayData.currentRenderables); + } + } + } + + List currentDataChangeEvents = new LinkedList(); + synchronized (dataChangeEvents) { + if (waitingOnObjects.size() == 0) { + currentDataChangeEvents.addAll(dataChangeEvents); + dataChangeEvents.clear(); + } else { + for (AbstractDispatchingObjectEvent dcEvent : dataChangeEvents) { + if (waitingOnObjects.contains(dcEvent.getObjectId()) == false) { + currentDataChangeEvents.add(dcEvent); + } + } + dataChangeEvents.removeAll(currentDataChangeEvents); + } + } + + displayData.dataManager.beginRender(target, paintProps); + + synchronized (renderingRouter) { + for (AbstractRemoteGraphicsEvent event : currentDataChangeEvents) { + renderingRouter.post(event); + } + + for (IRenderEvent event : currentRenderables) { + renderingRouter.post(event); + } + if (displayData.latestMouseLocation != null) { + renderingRouter.post(displayData.latestMouseLocation); + } + } + } + + public void lockObject(int objectId) { + synchronized (displayData.dataChangeEvents) { + displayData.waitingOnObjects.add(objectId); + } + } + + public void unlockObject(int objectId) { + synchronized (displayData.dataChangeEvents) { + displayData.waitingOnObjects.remove(objectId); + } + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + ISharedDisplaySession session = resourceData.getSession(); + displayData = new DisplayData(resourceData.getDisplayId(), session, + this); + ParticipantInitializedEvent event = new ParticipantInitializedEvent(); + event.setUserId(session.getUserID().getFQName()); + try { + session.registerEventHandler(this); + session.sendObjectToPeer(session.getCurrentDataProvider(), event); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void updateRenderFrameEvent(UpdateRenderFrameEvent event) { + if (event.getDisplayId() != resourceData.getDisplayId()) { + return; + } + int objectId = event.getObjectId(); + RenderFrameEvent frame = displayData.dataManager.getRenderableObject( + objectId, RenderFrameEvent.class, false); + if (frame == null) { + if (displayData.waitingOnFrames.contains(objectId) == false) { + RenderFrameNeededEvent needEvent = new RenderFrameNeededEvent(); + needEvent.setDisplayId(event.getDisplayId()); + needEvent.setObjectId(objectId); + ISharedDisplaySession session = resourceData.getSession(); + try { + session.sendObjectToPeer(session.getCurrentDataProvider(), + needEvent); + displayData.waitingOnFrames.add(objectId); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error sending message to data provider", e); + } + } + } else { + // We have the frame, apply update + RenderFrameEvent updated = null; + if (event.getRenderEvents().size() > 0) { + updated = new RenderFrameEvent(); + updated.setDisplayId(frame.getDisplayId()); + updated.setObjectId(objectId); + List events = new LinkedList(); + Iterator currIter = frame.getRenderEvents() + .iterator(); + Iterator updateIter = event.getRenderEvents() + .iterator(); + while (currIter.hasNext() && updateIter.hasNext()) { + IRenderEvent curr = currIter.next(); + IRenderEvent update = updateIter.next(); + IRenderEvent toUse = null; + if (update != null) { + if (update.getClass().equals(curr.getClass())) { + curr.applyDiffObject(update); + toUse = curr; + } else { + toUse = update; + } + } else { + toUse = curr; + } + events.add(toUse); + } + updated.setRenderEvents(events); + } else { + updated = frame; + } + // Render updated data + renderFrameEvent(updated); + } + } + + @Subscribe + public void renderFrameEvent(RenderFrameEvent event) { + if (event.getDisplayId() != resourceData.getDisplayId()) { + return; + } + if (event instanceof UpdateRenderFrameEvent == false) { + // Not an update event, new frame + int objectId = event.getObjectId(); + for (IRenderEvent re : event.getRenderEvents()) { + renderableArrived((AbstractRemoteGraphicsEvent) re.clone()); + } + displayData.dataManager.putRenderableObject(objectId, event); + } + issueRefresh(); + } + + @Subscribe + public void disposeRenderFrame(FrameDisposed event) { + if (event.getDisplayId() != resourceData.getDisplayId()) { + return; + } + displayData.waitingOnFrames.remove(event.getObjectId()); + displayData.dataManager.dispose(event.getObjectId()); + } + + @Subscribe + public void persitableArrived(final IPersistedEvent event) { + if (event.getDisplayId() != resourceData.getDisplayId()) { + return; + } + retrievePool.schedule(new Runnable() { + @Override + public void run() { + try { + AbstractDispatchingObjectEvent objectEvent = displayData.dataManager + .retrieveEvent(event); + if (objectEvent != null) { + renderableArrived(objectEvent); + } + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + }); + } + + public void postObjectEvent(AbstractDispatchingObjectEvent event) { + synchronized (displayData.renderingRouter) { + displayData.renderingRouter.post(event); + } + } + + @Subscribe + public void renderableArrived(AbstractRemoteGraphicsEvent event) { + if (event.getDisplayId() != resourceData.getDisplayId() + || event instanceof IRenderFrameEvent) { + // Skip IRenderFrameEvents, not applicable here + return; + } + if (event instanceof IRenderEvent) { + // Render based event + if (event instanceof BeginFrameEvent) { + // If begin frame event, clear current active renderables + displayData.activeRenderables.clear(); + displayData.activeRenderables.add((IRenderEvent) event); + } else if (event instanceof EndFrameEvent) { + synchronized (displayData.currentRenderables) { + IExtent current = null; + displayData.currentRenderables.clear(); + // Frame over, process BeginFrameEvent now to keep in sync + for (IRenderEvent renderable : displayData.activeRenderables) { + if (renderable instanceof BeginFrameEvent) { + // Handle begin frame event immediately before next + // paint occurs + final IRenderableDisplay display = descriptor + .getRenderableDisplay(); + final BeginFrameEvent bfe = (BeginFrameEvent) renderable; + display.setBackgroundColor(bfe.getColor()); + if (previousBounds == null + || previousBounds.equals(bfe.getBounds()) == false) { + previousBounds = bfe.getBounds(); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + resourceData.getEditor() + .setCanvasBounds( + bfe.getDisplayId(), + bfe.getBounds()); + display.getView().setExtent( + bfe.getExtent()); + } + }); + } else { + display.getView().setExtent(bfe.getExtent()); + } + current = bfe.getExtent(); + } else { + // Add to list for processing in paintInternal + displayData.currentRenderables.add(renderable); + } + } + displayData.activeRenderables.clear(); + displayData.renderableMap.put(current, + new ArrayList( + displayData.currentRenderables)); + } + issueRefresh(); + } else if (event instanceof MouseLocationEvent) { + displayData.latestMouseLocation = (MouseLocationEvent) event; + issueRefresh(); + } else { + displayData.activeRenderables.add((IRenderEvent) event); + } + } else if (event instanceof AbstractDispatchingObjectEvent) { + // If not IRenderEvent, event modifies data object + synchronized (displayData.dataChangeEvents) { + displayData.dataChangeEvents + .add((AbstractDispatchingObjectEvent) event); + } + issueRefresh(); + } else { + Activator.statusHandler.handle(Priority.PROBLEM, + "Could not handle event type: " + + event.getClass().getSimpleName()); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getResourceOrder() + */ + @Override + public ResourceOrder getResourceOrder() { + return ResourceOrder.LOWEST; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.cmenu.IContextMenuProvider#provideContextMenuItems + * (org.eclipse.jface.action.IMenuManager, int, int) + */ + @Override + public void provideContextMenuItems(IMenuManager menuManager, int x, int y) { + menuManager.add(new Action("Quit Session") { + @Override + public void run() { + System.out.println("TODO: Quit session"); + } + }); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResourceData.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResourceData.java new file mode 100644 index 0000000000..30a73bb510 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationResourceData.java @@ -0,0 +1,140 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * Resource data for a CollaborationResource. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 3, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class CollaborationResourceData extends AbstractResourceData { + + private ICollaborationEditor editor; + + private ISharedDisplaySession session; + + private int displayId; + + /** + * @param session2 + * @param displayId2 + */ + public CollaborationResourceData(ICollaborationEditor editor, + ISharedDisplaySession session, int displayId) { + this.session = session; + this.displayId = displayId; + this.editor = editor; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon + * .uf.viz.core.rsc.LoadProperties, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + @Override + public AbstractVizResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + return new CollaborationResource(this, loadProperties); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object + * ) + */ + @Override + public void update(Object updateData) { + fireChangeListeners(ChangeType.DATA_UPDATE, updateData); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return 31; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return true; + } + + /** + * @return the editor + */ + public ICollaborationEditor getEditor() { + return editor; + } + + /** + * @return the session + */ + public ISharedDisplaySession getSession() { + return session; + } + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationWrapperResource.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationWrapperResource.java new file mode 100644 index 0000000000..bb6c36bff9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationWrapperResource.java @@ -0,0 +1,388 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc; + +import java.util.Map; + +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ResourceCapabilityChanged; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ResourcePropertiesChanged; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IRefreshListener; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.Capabilities; +import com.raytheon.uf.viz.remote.graphics.DispatchGraphicsTarget; + +/** + * Collaboration resource that wraps an existing resource and extracts the + * proper target to use since the wrapped resource will not be sending paint + * events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationWrapperResource extends + AbstractVizResource implements + IResourceDataChanged { + + private AbstractVizResource wrappedResource; + + /** This listener exists to avoid .equals conflicts in listener list */ + private IResourceDataChanged capabilityChangeListener = new IResourceDataChanged() { + @Override + public void resourceChanged(ChangeType type, Object object) { + CollaborationWrapperResource.this.resourceChanged(type, object); + } + }; + + /** + * @param resourceData + * @param loadProperties + */ + public CollaborationWrapperResource( + CollaborationWrapperResourceData resourceData, + LoadProperties loadProperties, + AbstractVizResource wrappedResource) { + super(resourceData, loadProperties); + this.wrappedResource = wrappedResource; + wrappedResource.registerListener(new IRefreshListener() { + @Override + public void refresh() { + issueRefresh(); + } + }); + } + + /** + * @return the wrappedResource + */ + public AbstractVizResource getWrappedResource() { + return wrappedResource; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#disposeInternal() + */ + @Override + protected void disposeInternal() { + getResourceData().removeChangeListener(capabilityChangeListener); + getWrapperResourceData().removeChangeListener(capabilityChangeListener); + if (wrappedResource.getStatus() != ResourceStatus.DISPOSED) { + wrappedResource.dispose(); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#paintInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + if (target instanceof DispatchGraphicsTarget) { + target = ((DispatchGraphicsTarget) target).getWrappedObject(); + } + wrappedResource.paint(target, paintProps); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#initInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget) + */ + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + getResourceData().addChangeListener(capabilityChangeListener); + getWrapperResourceData().addChangeListener(capabilityChangeListener); + if (wrappedResource.getStatus() == ResourceStatus.NEW) { + if (target instanceof DispatchGraphicsTarget) { + target = ((DispatchGraphicsTarget) target).getWrappedObject(); + } + wrappedResource.init(target); + } + } + + /** + * @param + * @param capability + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getCapability(java.lang.Class) + */ + public C getCapability(Class capability) { + return wrappedResource.getCapability(capability); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getCapabilities() + */ + public Capabilities getCapabilities() { + return wrappedResource.getCapabilities(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getDescriptor() + */ + public IDescriptor getDescriptor() { + return wrappedResource.getDescriptor(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getDataTimes() + */ + public DataTime[] getDataTimes() { + return wrappedResource.getDataTimes(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getLoadProperties() + */ + public LoadProperties getLoadProperties() { + return wrappedResource.getLoadProperties(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getResourceData() + */ + public AbstractResourceData getResourceData() { + return wrappedResource.getResourceData(); + } + + public CollaborationWrapperResourceData getWrapperResourceData() { + return (CollaborationWrapperResourceData) resourceData; + } + + /** + * @param capability + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#hasCapability(java.lang.Class) + */ + public boolean hasCapability(Class capability) { + return wrappedResource.hasCapability(capability); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getName() + */ + public String getName() { + return wrappedResource.getName(); + } + + /** + * @param coord + * @return + * @throws VizException + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#inspect(com.raytheon.uf.common.geospatial.ReferencedCoordinate) + */ + public String inspect(ReferencedCoordinate coord) throws VizException { + return wrappedResource.inspect(coord); + } + + /** + * @param coord + * @return + * @throws VizException + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#interrogate(com.raytheon.uf.common.geospatial.ReferencedCoordinate) + */ + public Map interrogate(ReferencedCoordinate coord) + throws VizException { + return wrappedResource.interrogate(coord); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getStatus() + */ + public ResourceStatus getStatus() { + return wrappedResource.getStatus(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getResourceOrder() + */ + public ResourceOrder getResourceOrder() { + return wrappedResource.getResourceOrder(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#isTimeAgnostic() + */ + public boolean isTimeAgnostic() { + return wrappedResource.isTimeAgnostic(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getProperties() + */ + public ResourceProperties getProperties() { + return wrappedResource.getProperties(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getResourceContainer() + */ + public IDisplayPaneContainer getResourceContainer() { + return wrappedResource.getResourceContainer(); + } + + /** + * @return + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return wrappedResource.hashCode(); + } + + /** + * @param obj + * @return + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (super.equals(obj)) { + return true; + } + return wrappedResource.equals(obj); + } + + /** + * @param dataTime + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#remove(com.raytheon.uf.common.time.DataTime) + */ + public void remove(DataTime dataTime) { + wrappedResource.remove(dataTime); + } + + /** + * @return + * @see java.lang.Object#toString() + */ + public String toString() { + return wrappedResource.toString(); + } + + /** + * @param crs + * @throws VizException + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#project(org.opengis.referencing.crs.CoordinateReferenceSystem) + */ + public void project(CoordinateReferenceSystem crs) throws VizException { + wrappedResource.project(crs); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#okToUnload() + */ + public boolean okToUnload() { + return wrappedResource.okToUnload(); + } + + /** + * @param updatedProps + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#propertiesChanged(com.raytheon.uf.viz.core.rsc.ResourceProperties) + */ + public void propertiesChanged(ResourceProperties updatedProps) { + wrappedResource.propertiesChanged(updatedProps); + try { + ResourcePropertiesChanged event = new ResourcePropertiesChanged(); + event.setDisplayId(SharedEditorsManager + .getSharedDisplayId(getDescriptor().getRenderableDisplay())); + event.setResourceData(getResourceData()); + event.setProperties(updatedProps); + getWrapperResourceData().getSession().sendObjectToVenue(event); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.IResourceDataChanged#resourceChanged(com + * .raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType, + * java.lang.Object) + */ + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.CAPABILITY + && object instanceof AbstractCapability) { + try { + ResourceCapabilityChanged event = new ResourceCapabilityChanged(); + event.setDisplayId(SharedEditorsManager + .getSharedDisplayId(getDescriptor() + .getRenderableDisplay())); + event.setResourceData(getResourceData()); + event.setCapability((AbstractCapability) object); + getWrapperResourceData().getSession().sendObjectToVenue(event); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationWrapperResourceData.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationWrapperResourceData.java new file mode 100644 index 0000000000..232d542861 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/CollaborationWrapperResourceData.java @@ -0,0 +1,146 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * Collaboration resource data that wraps an existing resource data and + * constructs CollaborationWrapperResource which wraps the resource created by + * the wrapped resource data + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class CollaborationWrapperResourceData extends AbstractResourceData { + + @XmlElement + private AbstractResourceData wrappedResourceData; + + private ISharedDisplaySession session; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon + * .uf.viz.core.rsc.LoadProperties, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + @Override + public AbstractVizResource construct(LoadProperties loadProperties, + IDescriptor descriptor) throws VizException { + return new CollaborationWrapperResource(this, loadProperties, + wrappedResourceData.construct(loadProperties, descriptor)); + } + + /** + * @return the session + */ + public ISharedDisplaySession getSession() { + return session; + } + + /** + * @param session + * the session to set + */ + public void setSession(ISharedDisplaySession session) { + this.session = session; + } + + public AbstractResourceData getWrappedResourceData() { + return wrappedResourceData; + } + + /** + * @param wrappedResourceData + * the wrappedResourceData to set + */ + public void setWrappedResourceData(AbstractResourceData wrappedResourceData) { + this.wrappedResourceData = wrappedResourceData; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object + * ) + */ + @Override + public void update(Object updateData) { + wrappedResourceData.update(updateData); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return wrappedResourceData.hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) { + return wrappedResourceData.equals(obj); + } + CollaborationWrapperResourceData other = (CollaborationWrapperResourceData) obj; + if (wrappedResourceData == null) { + if (other.wrappedResourceData != null) + return false; + } else if (!wrappedResourceData.equals(other.wrappedResourceData)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/SelfAddingSystemResourceListener.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/SelfAddingSystemResourceListener.java new file mode 100644 index 0000000000..0e8bba11e2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/SelfAddingSystemResourceListener.java @@ -0,0 +1,89 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.ResourceList; +import com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener; + +/** + * Listener that manages a system resource and readds it when it is removed + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 13, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class SelfAddingSystemResourceListener implements RemoveListener { + + protected IDescriptor descriptor; + + private ResourcePair resource; + + public SelfAddingSystemResourceListener(AbstractResourceData resourceData, + IDescriptor descriptor) throws VizException { + this.descriptor = descriptor; + addResource(resourceData); + descriptor.getResourceList().addPostRemoveListener(this); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.ResourceList.RemoveListener#notifyRemove + * (com.raytheon.uf.viz.core.drawables.ResourcePair) + */ + @Override + public void notifyRemove(ResourcePair rp) throws VizException { + if (rp == resource) { + addResource(rp.getResourceData()); + } + } + + /** + * + */ + private void addResource(AbstractResourceData resourceData) + throws VizException { + resource = ResourcePair.constructSystemResourcePair(resourceData); + resource.instantiateResource(descriptor, true); + descriptor.getResourceList().add(resource); + } + + public void dispose() { + ResourceList resourceList = descriptor.getResourceList(); + resourceList.removePostRemoveListener(this); + resourceList.remove(resource); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/AbstractResourceChangedEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/AbstractResourceChangedEvent.java new file mode 100644 index 0000000000..219ed3fb58 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/AbstractResourceChangedEvent.java @@ -0,0 +1,85 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.event; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; + +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; + +/** + * Abstract resource changed event object, contains resource data of changed + * resource and displayId resource is on + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 28, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class AbstractResourceChangedEvent { + + @XmlAttribute + private int displayId; + + @XmlElement + private AbstractResourceData resourceData; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the resourceData + */ + public AbstractResourceData getResourceData() { + return resourceData; + } + + /** + * @param resourceData + * the resourceData to set + */ + public void setResourceData(AbstractResourceData resourceData) { + this.resourceData = resourceData; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ParticipantInitializedEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ParticipantInitializedEvent.java new file mode 100644 index 0000000000..fe60427007 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ParticipantInitializedEvent.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.event; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Event stating the participant has initialized and is ready for rendering + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 14, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ParticipantInitializedEvent { + + @DynamicSerializeElement + private String userId; + + /** + * @return the userId + */ + public String getUserId() { + return userId; + } + + /** + * @param userId + * the userId to set + */ + public void setUserId(String userId) { + this.userId = userId; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ReentrantEventHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ReentrantEventHandler.java new file mode 100644 index 0000000000..13ba8f4cd6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ReentrantEventHandler.java @@ -0,0 +1,201 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.event; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; + +/** + * An implementation of EventBus that posts all events to listeners immediately. + * The major difference between this implementation and the default + * implementation is that it allows reentrant posts, that is if you call post + * from within a handler it will immediately post the event while the default + * implementation will add the new event to a queue. Because EventBus is not + * designed for extension this is basically a reimplementation from scratch + * using the EventBus as an interface. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 13, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ReentrantEventHandler extends EventBus { + + private static class EventHandler { + + public final Method method; + + public final Object obj; + + public EventHandler(Method method, Object obj) { + this.method = method; + this.obj = obj; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((method == null) ? 0 : method.hashCode()); + result = prime * result + ((obj == null) ? 0 : obj.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + EventHandler other = (EventHandler) obj; + if (method == null) { + if (other.method != null) + return false; + } else if (!method.equals(other.method)) + return false; + // If obj.equals(other.obj) we still want the two ahndlers to be + // treated as different so we are only equal if obj == other.obj. + if (this.obj != other.obj) + return false; + return true; + } + + } + + private Map, Set> handlers = new HashMap, Set>(); + + @Override + public void post(Object obj) { + for (Class clazz : getClassHierarchy(obj.getClass())) { + Set handlers = this.handlers.get(clazz); + if (handlers == null) { + return; + } + for (EventHandler handler : handlers) { + try { + handler.method.invoke(handler.obj, new Object[] { obj }); + } catch (IllegalAccessException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } catch (InvocationTargetException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + } + + private List> getClassHierarchy(Class clazz) { + List> result = new ArrayList>(); + while (clazz != null) { + result.add(clazz); + result.addAll(Arrays.asList(clazz.getInterfaces())); + clazz = clazz.getSuperclass(); + } + return result; + } + + @Override + public void register(Object object) { + Class objClazz = object.getClass(); + for (Class clazz : getClassHierarchy(objClazz)) { + for (Method method : clazz.getMethods()) { + if (method.isAnnotationPresent(Subscribe.class)) { + Class[] types = method.getParameterTypes(); + if (types.length != 1) { + throw new IllegalStateException(method.getName() + + " has the wrong number of arguments"); + } + Class type = types[0]; + Set handlers = this.handlers.get(type); + if (handlers == null) { + handlers = new HashSet(); + this.handlers.put(type, handlers); + } + try { + // get the actual method from the obj so that if there + // are any overrides they are handled correctly. + Method objMethod = objClazz.getMethod(method.getName(), + method.getParameterTypes()); + handlers.add(new EventHandler(objMethod, object)); + } catch (NoSuchMethodException e) { + // This method will exist, this exception will never + // happen. + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + } + } + + @Override + public void unregister(Object object) { + // This is a brute force algorithm, more efficient algorithms could be + // written but are currently not needed + boolean removed = false; + Iterator, Set>> entryItr = handlers + .entrySet().iterator(); + while (entryItr.hasNext()) { + Set handlers = entryItr.next().getValue(); + Iterator handlerItr = handlers.iterator(); + while (handlerItr.hasNext()) { + if (handlerItr.next().obj == object) { + handlerItr.remove(); + removed = true; + } + } + if (handlers.isEmpty()) { + entryItr.remove(); + } + } + if (!removed) { + throw new IllegalArgumentException("Object was never registered: " + + object); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ResourceCapabilityChanged.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ResourceCapabilityChanged.java new file mode 100644 index 0000000000..32abfae367 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ResourceCapabilityChanged.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.event; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; + +/** + * Event to notify a shared resource capability changed + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class ResourceCapabilityChanged extends AbstractResourceChangedEvent + implements ISerializableObject { + + @XmlElement + private AbstractCapability capability; + + /** + * @return the capability + */ + public AbstractCapability getCapability() { + return capability; + } + + /** + * @param capability + * the capability to set + */ + public void setCapability(AbstractCapability capability) { + this.capability = capability; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ResourcePropertiesChanged.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ResourcePropertiesChanged.java new file mode 100644 index 0000000000..ae34a57068 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/ResourcePropertiesChanged.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.event; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; + +/** + * Event class for notifying changes to a shared resources' properties + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 28, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class ResourcePropertiesChanged extends AbstractResourceChangedEvent + implements ISerializableObject { + + @XmlElement + private ResourceProperties properties; + + /** + * @return the properties + */ + public ResourceProperties getProperties() { + return properties; + } + + /** + * @param properties + * the properties to set + */ + public void setProperties(ResourceProperties properties) { + this.properties = properties; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/SharedResource.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/SharedResource.java new file mode 100644 index 0000000000..1dc49e6913 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/event/SharedResource.java @@ -0,0 +1,109 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.event; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.viz.core.drawables.ResourcePair; + +/** + * Shared resource object, specifies a resource shared by all users in the + * venue. Can send command to add resource or remove + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 10, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement +public class SharedResource implements ISerializableObject { + + @XmlAttribute + private int displayId; + + @XmlAttribute + private boolean removeResource = false; + + @XmlElement + private ResourcePair resource; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the resource + */ + public ResourcePair getResource() { + return resource; + } + + /** + * @param resource + * the resource to set + */ + public void setResource(ResourcePair resource) { + this.resource = resource; + } + + /** + * Returns true if the SharedResource represents a resource removal, false + * if addition + * + * @return the remove + */ + public boolean isRemoveResource() { + return removeResource; + } + + /** + * @param remove + * the remove to set + */ + public void setRemoveResource(boolean remove) { + this.removeResource = remove; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/CollaborationRenderingDataManager.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/CollaborationRenderingDataManager.java new file mode 100644 index 0000000000..6799ada04c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/CollaborationRenderingDataManager.java @@ -0,0 +1,292 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; + +import com.google.common.eventbus.EventBus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.rsc.CollaborationResource; +import com.raytheon.uf.viz.collaboration.display.storage.CollaborationObjectEventStorage; +import com.raytheon.uf.viz.collaboration.display.storage.IObjectEventRetrieval; +import com.raytheon.uf.viz.collaboration.display.storage.IPersistedEvent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Collaboration rendering data manager, manages render data and render handlers + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationRenderingDataManager implements IObjectEventRetrieval { + + private static final String RENDERING_EXTENSION = "com.raytheon.uf.viz.collaboration.display.renderingExtension"; + + private static Collection handlerElements = new LinkedList(); + + static { + IExtensionRegistry registry = Platform.getExtensionRegistry(); + if (registry != null) { + IExtensionPoint point = registry + .getExtensionPoint(RENDERING_EXTENSION); + if (point != null) { + IExtension[] extensions = point.getExtensions(); + + for (IExtension ext : extensions) { + IConfigurationElement[] config = ext + .getConfigurationElements(); + handlerElements.addAll(Arrays.asList(config)); + } + } + } + } + + private Map renderableObjectMap = new HashMap(); + + private IGraphicsTarget target; + + private PaintProperties paintProps; + + private EventBus disposerRouter; + + private IObjectEventRetrieval retrieval; + + private CollaborationResource resource; + + private int displayId; + + public CollaborationRenderingDataManager(ISharedDisplaySession session, + CollaborationResource resource, int displayId) { + this.resource = resource; + this.disposerRouter = new EventBus(); + this.retrieval = CollaborationObjectEventStorage.createRetrievalObject( + session, displayId); + this.displayId = displayId; + } + + /** + * @param target + * @param paintProps + */ + public void beginRender(IGraphicsTarget target, PaintProperties paintProps) { + this.target = target; + this.paintProps = paintProps; + } + + /** + * @return the target + */ + public IGraphicsTarget getGraphicsTarget() { + return target; + } + + /** + * @return the paintProperties + */ + public PaintProperties getPaintProperties() { + return paintProps; + } + + /** + * Put a renderable object in the object map. If an object already exists + * for that id, it will be sent to the disposer + * + * @param objectId + * @param obj + */ + public void putRenderableObject(int objectId, Object obj) { + if (obj != null) { + Object[] objects = null; + if (obj.getClass().isArray()) { + objects = (Object[]) obj; + } else { + objects = new Object[] { obj }; + } + Object[] oldValue = renderableObjectMap.put(objectId, objects); + if (oldValue != null) { + dispose(oldValue); + } + } + } + + /** + * Get a renderable object out of the object map as the objectType, if no + * object exists or the object is not of type objectType, null is returned. + * Use Object[].class as the objectType if you want all objects bound to the + * id. The first object in the array that is of type objectType will be + * returned otherwise + * + * @param + * @param objectId + * @param objectType + * @return + */ + public T getRenderableObject(int objectId, Class objectType) { + return getRenderableObject(objectId, objectType, true); + } + + public T getRenderableObject(int objectId, Class objectType, + boolean retrieve) { + T obj = null; + Object[] toCheck = renderableObjectMap.get(objectId); + if (toCheck != null) { + if (objectType == Object[].class) { + obj = objectType.cast(toCheck); + } else { + for (Object check : toCheck) { + if (objectType.isInstance(check)) { + obj = objectType.cast(check); + break; + } + } + } + } else if (retrieve) { + try { + resource.lockObject(objectId); + AbstractDispatchingObjectEvent[] events = retrieveObjectEvents(objectId); + for (AbstractDispatchingObjectEvent event : events) { + resource.postObjectEvent(event); + } + return getRenderableObject(objectId, objectType, false); + } catch (CollaborationException e) { + Activator.statusHandler.handle( + Priority.PROBLEM, + "Error retrieving object events: " + + e.getLocalizedMessage(), e); + } finally { + resource.unlockObject(objectId); + } + } + return obj; + } + + /** + * Disposes all renderable data for the object + * + * @param objectId + */ + public void dispose(int objectId) { + Object[] objects = renderableObjectMap.remove(objectId); + if (objects != null) { + dispose(objects); + } + } + + /** + * Dispose all renderable object data + */ + public void dispose() { + for (Object[] obj : renderableObjectMap.values()) { + dispose(obj); + } + renderableObjectMap.clear(); + } + + /** + * Disposes a single renderable object by sending it to the disposer + * EventBus + * + * @param obj + */ + public void dispose(Object[] objects) { + for (Object toDispose : objects) { + disposerRouter.post(toDispose); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval + * #retrieveEvent + * (com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedEvent) + */ + @Override + public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event) + throws CollaborationException { + return retrieval.retrieveEvent(event); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval + * #retrieveObjectEvents(int) + */ + @Override + public AbstractDispatchingObjectEvent[] retrieveObjectEvents(int objectId) + throws CollaborationException { + return retrieval.retrieveObjectEvents(objectId); + } + + /** + * @param dataManager + * @return + */ + public static synchronized Collection createRenderingHandlers( + CollaborationRenderingDataManager dataManager) { + List handlers = new ArrayList( + handlerElements.size()); + for (IConfigurationElement element : handlerElements) { + try { + CollaborationRenderingHandler handler = (CollaborationRenderingHandler) element + .createExecutableExtension("class"); + handler.setDataManager(dataManager); + handlers.add(handler); + dataManager.disposerRouter.register(handler); + } catch (CoreException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + return handlers; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/CollaborationRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/CollaborationRenderingHandler.java new file mode 100644 index 0000000000..165f625c50 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/CollaborationRenderingHandler.java @@ -0,0 +1,59 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.PaintProperties; + +/** + * An abstract class which contains a reference to the dataManager the + * subclasses will use for data access, also has convenience methods for + * accessing current target and paint properties + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public abstract class CollaborationRenderingHandler { + + protected CollaborationRenderingDataManager dataManager; + + final void setDataManager(CollaborationRenderingDataManager dataManager) { + this.dataManager = dataManager; + } + + protected final IGraphicsTarget getGraphicsTarget() { + return dataManager.getGraphicsTarget(); + } + + protected final PaintProperties getPaintProperties() { + return dataManager.getPaintProperties(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/GeneralRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/GeneralRenderingHandler.java new file mode 100644 index 0000000000..1692ec79cb --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/GeneralRenderingHandler.java @@ -0,0 +1,142 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import org.eclipse.swt.graphics.RGB; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.MouseLocationEvent; +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.clipping.ClearClippingPane; +import com.raytheon.uf.viz.remote.graphics.events.clipping.SetupClippingPane; +import com.raytheon.uf.viz.remote.graphics.events.points.DrawPointsEvent; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Handles general rendering events, begin frame and dispose + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class GeneralRenderingHandler extends CollaborationRenderingHandler { + + /** + * General dispose of a renderable object event + * + * @param event + */ + @Subscribe + public void disposeRenderable(DisposeObjectEvent event) { + dataManager.dispose(event.getObjectId()); + } + + @Subscribe + public void handleDrawPoints(DrawPointsEvent event) { + try { + IGraphicsTarget target = getGraphicsTarget(); + target.drawPoints(event.getPointsCollection(), event.getColor(), + event.getStyle(), event.getMagnification()); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void handleEndFrame(MouseLocationEvent event) { + // TODO: Draw the best icon for a cursor, for now will use what + // VizDisplayPane uses, this is copypasta + double[] mouseLoc = event.getMouseLocation(); + if (mouseLoc == null) { + // Don't draw if no location + return; + } + + IGraphicsTarget target = getGraphicsTarget(); + PaintProperties paintProps = getPaintProperties(); + target.clearClippingPlane(); + // Calculate scale for image + double screenToWorldRatio = paintProps.getCanvasBounds().width + / paintProps.getView().getExtent().getWidth(); + double middleValue = 5 / screenToWorldRatio; + double outsideValue = 6 / screenToWorldRatio; + double insideValue = 4 / screenToWorldRatio; + + Coordinate virtualCursor = new Coordinate(mouseLoc[0], mouseLoc[1]); + + try { + target.drawRect(new PixelExtent(virtualCursor.x - middleValue, + virtualCursor.x + middleValue, virtualCursor.y + - middleValue, virtualCursor.y + middleValue), + new RGB(255, 255, 255), 1.0f, 1.0f); + + target.drawRect(new PixelExtent(virtualCursor.x - outsideValue, + virtualCursor.x + outsideValue, virtualCursor.y + - outsideValue, virtualCursor.y + outsideValue), + new RGB(0, 0, 0), 0.5f, 1.0f); + + target.drawRect(new PixelExtent(virtualCursor.x - insideValue, + virtualCursor.x + insideValue, virtualCursor.y + - insideValue, virtualCursor.y + insideValue), + new RGB(0, 0, 0), 0.5f, 1.0f); + + DrawableCircle circle = new DrawableCircle(); + circle.filled = true; + circle.radius = 1.0 / screenToWorldRatio; + circle.basics.color = new RGB(255, 255, 255); + circle.numberOfPoints = 4; + circle.setCoordinates(virtualCursor.x, virtualCursor.y); + target.drawCircle(circle); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } finally { + target.setupClippingPlane(paintProps.getClippingPane()); + } + } + + @Subscribe + public void clearClippingPane(ClearClippingPane event) { + getGraphicsTarget().clearClippingPlane(); + } + + @Subscribe + public void setupClippingPane(SetupClippingPane event) { + getGraphicsTarget().setupClippingPlane(event.getExtent()); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java new file mode 100644 index 0000000000..cfcbf866c5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ImagingRenderingHandler.java @@ -0,0 +1,446 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import java.awt.image.RenderedImage; +import java.util.ArrayList; +import java.util.List; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.colormap.IColorMap; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.core.DrawableImage; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IMesh; +import com.raytheon.uf.viz.core.PixelCoverage; +import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback; +import com.raytheon.uf.viz.core.data.IRenderedImageCallback; +import com.raytheon.uf.viz.core.drawables.ColorMapParameters; +import com.raytheon.uf.viz.core.drawables.IColormappedImage; +import com.raytheon.uf.viz.core.drawables.IImage; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension; +import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension.IMosaicImage; +import com.raytheon.uf.viz.core.drawables.ext.IMosaicMaxValImageExtension; +import com.raytheon.uf.viz.core.drawables.ext.IMosaicOrderedImageExtension; +import com.raytheon.uf.viz.core.drawables.ext.ISingleColorImageExtension; +import com.raytheon.uf.viz.core.drawables.ext.ISingleColorImageExtension.ISingleColorImage; +import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.map.IMapMeshExtension; +import com.raytheon.uf.viz.remote.graphics.events.colormap.ColorMapDataEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.CreateColorMapEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.CreateColormappedImageEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.DrawColorRampEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParametersEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.CreateIImageEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.CreateSingleColorImage; +import com.raytheon.uf.viz.remote.graphics.events.imagery.PaintImageEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.PaintImagesEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.RenderedImageEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.UpdateImageDataEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.UpdateSingleColorImage; +import com.raytheon.uf.viz.remote.graphics.events.mesh.CreateMeshEvent; +import com.raytheon.uf.viz.remote.graphics.events.mesh.ReprojectMeshEvent; +import com.raytheon.uf.viz.remote.graphics.events.mosaic.CreateMosaicImageEvent; +import com.raytheon.uf.viz.remote.graphics.events.mosaic.UpdateImagesToMosaic; +import com.raytheon.uf.viz.remote.graphics.events.mosaic.UpdateMosaicExtent; +import com.raytheon.uf.viz.remote.graphics.extensions.DispatchingMosaicMaxValExtension; +import com.raytheon.uf.viz.remote.graphics.extensions.DispatchingMosaicOrderedExtension; + +/** + * Handles render events for imagery/mesh objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ImagingRenderingHandler extends CollaborationRenderingHandler { + + private Object colorMapLock = new Object(); + + @Subscribe + public void renderImages(PaintImagesEvent event) { + PaintProperties paintProps = getPaintProperties(); + IGraphicsTarget target = getGraphicsTarget(); + PaintImageEvent[] events = event.getObjects(); + DrawableImage[] images = toDrawableImages(events, dataManager); + if (images.length > 0) { + PaintProperties imageProps = new PaintProperties(paintProps); + imageProps.setAlpha(event.getAlpha()); + try { + target.drawRasters(imageProps, images); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + /** + * Converts PaintImageEvent[] into DrawableImage[] by looking up image and + * mesh objects from dataManager + * + * @param events + * @param dataManager + * @return + */ + public static DrawableImage[] toDrawableImages(PaintImageEvent[] events, + CollaborationRenderingDataManager dataManager) { + List images = new ArrayList(events.length); + for (PaintImageEvent pie : events) { + IImage image = dataManager.getRenderableObject(pie.getObjectId(), + IImage.class); + if (image != null) { + PixelCoverage coverage = new PixelCoverage(pie.getUl(), + pie.getUr(), pie.getLr(), pie.getLl()); + int meshId = pie.getMeshId(); + if (meshId > -1) { + IMesh mesh = dataManager.getRenderableObject( + pie.getMeshId(), IMesh.class); + if (mesh != null) { + coverage.setMesh(mesh); + } + } + images.add(new DrawableImage(image, coverage)); + } + } + return images.toArray(new DrawableImage[images.size()]); + } + + @Subscribe + public void updateImageData(UpdateImageDataEvent event) { + IImage image = dataManager.getRenderableObject(event.getObjectId(), + IImage.class); + if (image != null) { + image.setBrightness(event.getBrightness()); + image.setContrast(event.getContrast()); + image.setInterpolated(event.isInterpolated()); + } + } + + @Subscribe + public void disposeImage(IImage image) { + image.dispose(); + } + + // ================== RenderedImage events ================== + + public class RenderedImageDataCallback implements IRenderedImageCallback { + private RenderedImage image; + + @Override + public RenderedImage getImage() throws VizException { + RenderedImage rval = image; + if (image != null) { + image = null; + } + return rval; + } + + public void setData(RenderedImage image) { + this.image = image; + } + } + + @Subscribe + public void createImage(CreateIImageEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + RenderedImageDataCallback callback = new RenderedImageDataCallback(); + IImage image = target.initializeRaster(callback); + dataManager.putRenderableObject(event.getObjectId(), new Object[] { + image, callback }); + } + + @Subscribe + public void disposeCallback(RenderedImageDataCallback callback) { + callback.setData(null); + } + + @Subscribe + public void handleRenderedImage(RenderedImageEvent event) { + RenderedImageDataCallback callback = dataManager.getRenderableObject( + event.getObjectId(), RenderedImageDataCallback.class); + if (callback != null) { + callback.setData(event.getRenderedImage()); + } + } + + // ================== IColormappedImage events ================== + + /** + * TODO: Manage ColorMaps better! (sharing and updating) + * + * Creates an IColormappedImage object from the event + * + * @param event + * @throws VizException + */ + @Subscribe + public void createColormappedImage(CreateColormappedImageEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + int imageId = event.getObjectId(); + IColorMapDataRetrievalCallback callback = new ColorMapDataCallback(); + UpdateColorMapParametersEvent cmapParamEvent = event + .getColorMapParameters(); + ColorMapParameters params = null; + if (cmapParamEvent != null) { + params = cmapParamEvent.getColorMapParameters(); + if (event.getColorMap() != null && params != null) { + params.setColorMap(event.getColorMap().getColorMap()); + } + } + try { + IColormappedImage image = target.getExtension( + IColormappedImageExtension.class).initializeRaster( + callback, params); + dataManager.putRenderableObject(imageId, new Object[] { image, + callback }); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void updateColorMapParameters(UpdateColorMapParametersEvent event) { + IColormappedImage image = dataManager.getRenderableObject( + event.getObjectId(), IColormappedImage.class); + if (image != null) { + ColorMapParameters newParams = event.getColorMapParameters(); + synchronized (colorMapLock) { + ColorMapParameters params = image.getColorMapParameters(); + if (params != null && newParams != null) { + newParams.setColorMap(params.getColorMap()); + } + image.setColorMapParameters(newParams); + } + } + } + + @Subscribe + public void updateColorMap(UpdateColorMapEvent event) { + IColormappedImage image = dataManager.getRenderableObject( + event.getObjectId(), IColormappedImage.class); + if (image != null) { + IColorMap colorMap = event.getColorMap(); + synchronized (colorMapLock) { + ColorMapParameters params = image.getColorMapParameters(); + if (params == null && colorMap != null) { + params = new ColorMapParameters(); + params.setColorMap(colorMap); + image.setColorMapParameters(params); + } else if (params != null) { + params.setColorMap(colorMap); + } + } + } + } + + @Subscribe + public void dataArrived(ColorMapDataEvent event) { + ColorMapDataCallback callback = dataManager.getRenderableObject( + event.getObjectId(), ColorMapDataCallback.class); + if (callback != null) { + callback.setData(event.getColorMapData()); + } + } + + @Subscribe + public void disposeColorMapCallback(ColorMapDataCallback callback) { + callback.setData(null); + } + + // TODO: Put utility classes in same package + + public class ColorMapDataCallback implements IColorMapDataRetrievalCallback { + private ColorMapData data; + + @Override + public ColorMapData getColorMapData() throws VizException { + ColorMapData rval = data; + if (data != null) { + data = null; + } + return rval; + } + + public void setData(ColorMapData data) { + this.data = data; + } + } + + // ================== IMesh events ================== + + @Subscribe + public void createMesh(CreateMeshEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + int meshId = event.getObjectId(); + try { + IMesh mesh = target.getExtension(IMapMeshExtension.class) + .constructMesh(event.getImageGeometry(), + event.getTargetGeometry()); + dataManager.putRenderableObject(meshId, mesh); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void reprojectMesh(ReprojectMeshEvent event) { + IMesh mesh = dataManager.getRenderableObject(event.getObjectId(), + IMesh.class); + if (mesh != null) { + try { + mesh.reproject(event.getTargetGeometry()); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + @Subscribe + public void disposeMesh(IMesh mesh) { + mesh.dispose(); + } + + // ================== ISingleColorImage events ================== + + @Subscribe + public void createSingleColorImage(CreateSingleColorImage event) { + IGraphicsTarget target = getGraphicsTarget(); + RenderedImageDataCallback callback = new RenderedImageDataCallback(); + int imageId = event.getObjectId(); + try { + ISingleColorImage image = target.getExtension( + ISingleColorImageExtension.class).constructImage(callback, + event.getColor()); + dataManager.putRenderableObject(imageId, new Object[] { image, + callback }); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void updateSingleColorImage(UpdateSingleColorImage event) { + ISingleColorImage image = dataManager.getRenderableObject( + event.getObjectId(), ISingleColorImage.class); + if (image != null) { + image.setColor(event.getColor()); + } + } + + // ================== IColorMap events ================== + + @Subscribe + public void handleCreateColorMap(CreateColorMapEvent event) { + int objectId = event.getObjectId(); + dataManager.putRenderableObject(objectId, event.getColorMap()); + } + + @Subscribe + public void drawColorRamp(DrawColorRampEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + IColorMap colorMap = dataManager.getRenderableObject( + event.getColorMapId(), IColorMap.class); + if (colorMap != null) { + try { + target.drawColorRamp(event.getDrawableColorMap(colorMap)); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + // ================== IMosaicImage events ================== + + @Subscribe + public void createMosaicImage(CreateMosaicImageEvent event) { + int imageId = event.getObjectId(); + IGraphicsTarget target = getGraphicsTarget(); + IExtent imageExtent = null; + ColorMapParameters parameters = null; + if (event.getExtent() != null) { + imageExtent = event.getExtent().getExtent(); + } + if (event.getColorMapParameters() != null) { + parameters = event.getColorMapParameters().getColorMapParameters(); + if (event.getColorMap() != null && parameters != null) { + parameters.setColorMap(event.getColorMap().getColorMap()); + } + } + Class extensionClass = IMosaicImageExtension.class; + if (DispatchingMosaicMaxValExtension.MOSAIC_TYPE.equals(event + .getMosaicType())) { + extensionClass = IMosaicMaxValImageExtension.class; + } else if (DispatchingMosaicOrderedExtension.MOSAIC_TYPE.equals(event + .getMosaicType())) { + extensionClass = IMosaicOrderedImageExtension.class; + } + try { + + dataManager.putRenderableObject( + imageId, + target.getExtension(extensionClass).initializeRaster( + event.getBounds(), imageExtent, parameters)); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void updateImagesToMosaic(UpdateImagesToMosaic event) { + IMosaicImage image = dataManager.getRenderableObject( + event.getObjectId(), IMosaicImage.class); + if (image != null) { + image.setImagesToMosaic(ImagingRenderingHandler.toDrawableImages( + event.getImagesToMosaic(), dataManager)); + } + } + + @Subscribe + public void updateMosaicImageExtent(UpdateMosaicExtent event) { + IMosaicImage image = dataManager.getRenderableObject( + event.getObjectId(), IMosaicImage.class); + if (image != null) { + image.setImageExtent(event.getExtent()); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/PrimitiveRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/PrimitiveRenderingHandler.java new file mode 100644 index 0000000000..5833fb668e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/PrimitiveRenderingHandler.java @@ -0,0 +1,101 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.DrawableLine; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawCircleEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawCirclesEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawLineEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawLinesEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawRectEvent; + +/** + * Rendering handler for primitive shapes (lines, rectangles, circles) + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class PrimitiveRenderingHandler extends CollaborationRenderingHandler { + + @Subscribe + public void drawCircles(DrawCirclesEvent event) { + DrawCircleEvent[] events = event.getObjects(); + DrawableCircle[] circles = new DrawableCircle[events.length]; + for (int i = 0; i < events.length; ++i) { + circles[i] = events[i].getDrawableCircle(); + } + try { + getGraphicsTarget().drawCircle(circles); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void drawLines(DrawLinesEvent event) { + DrawLineEvent[] events = event.getObjects(); + DrawableLine[] lines = new DrawableLine[events.length]; + for (int i = 0; i < events.length; ++i) { + lines[i] = events[i].getDrawableLine(); + } + try { + getGraphicsTarget().drawLine(lines); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void drawRect(DrawRectEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + try { + if (event.getFilled()) { + target.drawShadedRect(event.getExtent(), event.getColor(), + event.getAlpha(), event.getFillPattern()); + } else { + target.drawRect(event.getExtent(), event.getColor(), + event.getLineWidth(), event.getAlpha()); + } + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java new file mode 100644 index 0000000000..87ee128095 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/ShapeRenderingHandler.java @@ -0,0 +1,277 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import java.util.HashMap; + +import org.eclipse.swt.graphics.RGB; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IShadedShape; +import com.raytheon.uf.viz.core.drawables.IShape; +import com.raytheon.uf.viz.core.drawables.IWireframeShape; +import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormapShadedShapeExtension; +import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormapShadedShapeExtension.IColormapShadedShape; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.events.shapes.AbstractShadedShapeData.DataSpace; +import com.raytheon.uf.viz.remote.graphics.events.shapes.AllocatePointsEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.ColormappedShadedShapeDataEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.ColormappedShadedShapeDataEvent.ColormappedShadedGeometryData; +import com.raytheon.uf.viz.remote.graphics.events.shapes.ColormappedShadedShapeDataEvent.ColormappedShadedShapeData; +import com.raytheon.uf.viz.remote.graphics.events.shapes.CreateColormappedShadedShape; +import com.raytheon.uf.viz.remote.graphics.events.shapes.CreateShadedShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.CreateWireframeShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.DrawShadedShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.DrawShadedShapesEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.RenderColormappedShadedShape; +import com.raytheon.uf.viz.remote.graphics.events.shapes.RenderWireframeShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.SetShadedShapeFillPattern; +import com.raytheon.uf.viz.remote.graphics.events.shapes.ShadedShapeDataEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.ShadedShapeDataEvent.ShadedShapeData; +import com.raytheon.uf.viz.remote.graphics.events.shapes.WireframeShapeDataEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.WireframeShapeDataEvent.Label; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.LineString; + +/** + * Handles render events for IShapes + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class ShapeRenderingHandler extends CollaborationRenderingHandler { + + @Subscribe + public void createWireframeShape(CreateWireframeShapeEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + int shapeId = event.getObjectId(); + IWireframeShape shape = null; + if (event.getSimplificationLevel() != null) { + if (event.isSpatialChopFlag() != null) { + shape = target.createWireframeShape(event.isMutable(), + event.getGridGeometry(), + event.getSimplificationLevel(), + event.isSpatialChopFlag(), event.getIExtent()); + } else { + shape = target + .createWireframeShape(event.isMutable(), + event.getGridGeometry(), + event.getSimplificationLevel()); + } + } else { + shape = target.createWireframeShape(event.isMutable(), + event.getGridGeometry()); + } + dataManager.putRenderableObject(shapeId, shape); + } + + @Subscribe + public void createShadedShape(CreateShadedShapeEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + int shapeId = event.getObjectId(); + IShadedShape shape = target.createShadedShape(event.isMutable(), + event.getTargetGeometry(), event.isTesselate()); + dataManager.putRenderableObject(shapeId, shape); + } + + @Subscribe + public void createColormapShadedShape(CreateColormappedShadedShape event) { + IGraphicsTarget target = getGraphicsTarget(); + try { + IColormapShadedShapeExtension ext = target + .getExtension(IColormapShadedShapeExtension.class); + IColormapShadedShape shape = ext.createColormapShadedShape( + event.getTargetGeometry(), event.isTesselate()); + dataManager.putRenderableObject(event.getObjectId(), shape); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void allocatePointsForShape(AllocatePointsEvent event) { + IWireframeShape shape = dataManager.getRenderableObject( + event.getObjectId(), IWireframeShape.class); + if (shape != null) { + shape.allocate(event.getNumberOfPoints()); + } + } + + @Subscribe + public void wireframeShapeDataArrived(WireframeShapeDataEvent event) { + IWireframeShape shape = dataManager.getRenderableObject( + event.getObjectId(), IWireframeShape.class); + if (shape != null) { + shape.reset(); + for (Label label : event.getLabels()) { + shape.addLabel(label.getText(), label.getPoint()); + } + for (double[][] coords : event.getPixelCoordinates()) { + shape.addLineSegment(coords); + } + for (Coordinate[] coords : event.getWorldCoordiantes()) { + shape.addLineSegment(coords); + } + if (event.isCompile()) { + shape.compile(); + } + } + } + + @Subscribe + public void shadedShapeDataArrived(ShadedShapeDataEvent event) { + IShadedShape shape = dataManager.getRenderableObject( + event.getObjectId(), IShadedShape.class); + if (shape != null) { + shape.reset(); + for (ShadedShapeData data : event.getShapeData()) { + if (data.getDataSpace() == DataSpace.PIXEL) { + shape.addPolygonPixelSpace(data.getContour(), + data.getInfo()); + } else if (data.getDataSpace() == DataSpace.WORLD) { + shape.addPolygon(data.getContour(), data.getInfo()); + } + } + if (event.isCompile()) { + shape.compile(); + } + } + } + + @Subscribe + public void colormapShadedShapeDataArrived( + ColormappedShadedShapeDataEvent event) { + IColormapShadedShape shape = dataManager.getRenderableObject( + event.getObjectId(), IColormapShadedShape.class); + if (shape != null) { + shape.reset(); + for (ColormappedShadedShapeData data : event.getShapeData()) { + LineString[] contour = data.getContour(); + Integer key = data.getInfo(); + if (data.getDataSpace() == DataSpace.WORLD) { + shape.addPolygon(contour, key); + } else { + shape.addPolygonPixelSpace(contour, key); + } + } + for (ColormappedShadedGeometryData data : event.getGeometryData()) { + shape.addGeometry(data.getGeometry(), data.getColorKey()); + } + if (event.isCompile()) { + shape.compile(); + } + } + } + + @Subscribe + public void setShadedShapeFillPattern(SetShadedShapeFillPattern event) { + int shapeId = event.getObjectId(); + IShadedShape shape = dataManager.getRenderableObject(shapeId, + IShadedShape.class); + if (shape != null) { + shape.setFillPattern(event.getFillPattern()); + } + } + + @Subscribe + public void renderWireframeShape(RenderWireframeShapeEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + IWireframeShape shape = dataManager.getRenderableObject( + event.getObjectId(), IWireframeShape.class); + if (shape != null) { + IFont font = null; + if (event.getFontId() != null) { + font = dataManager.getRenderableObject(event.getFontId(), + IFont.class); + } + try { + if (event.getAlpha() == null) { + target.drawWireframeShape(shape, event.getColor(), + event.getLineWidth(), event.getLineStyle(), font); + } else { + target.drawWireframeShape(shape, event.getColor(), + event.getLineWidth(), event.getLineStyle(), font, + event.getAlpha()); + } + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + @Subscribe + public void renderShadedShapes(DrawShadedShapesEvent event) { + DrawShadedShapeEvent[] shapeEvents = event.getObjects(); + float alpha = event.getAlpha(); + float brightness = event.getBrightness(); + IShadedShape[] shapes = new IShadedShape[shapeEvents.length]; + for (int i = 0; i < shapes.length; ++i) { + shapes[i] = dataManager.getRenderableObject( + shapeEvents[i].getObjectId(), IShadedShape.class); + } + try { + getGraphicsTarget().drawShadedShapes(alpha, brightness, shapes); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void renderColormapShadedShape(RenderColormappedShadedShape event) { + IColormapShadedShape shape = dataManager.getRenderableObject( + event.getObjectId(), IColormapShadedShape.class); + if (shape != null) { + try { + IGraphicsTarget target = getGraphicsTarget(); + IColormapShadedShapeExtension extension = target + .getExtension(IColormapShadedShapeExtension.class); + extension.drawColormapShadedShape(shape, + new HashMap(event.getColorMap()), + event.getAlpha(), event.getBrightness()); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + @Subscribe + public void disposeShape(IShape shape) { + shape.dispose(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/StringRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/StringRenderingHandler.java new file mode 100644 index 0000000000..8947ec907b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/rendering/StringRenderingHandler.java @@ -0,0 +1,123 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.rendering; + +import java.io.File; +import java.io.IOException; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.util.FileUtil; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.events.fonts.CreateFontEvent; +import com.raytheon.uf.viz.remote.graphics.events.fonts.UpdateFontDataEvent; +import com.raytheon.uf.viz.remote.graphics.events.strings.DrawStringEvent; +import com.raytheon.uf.viz.remote.graphics.events.strings.DrawStringsEvent; + +/** + * Rendering handler for strings and fonts + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 10, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class StringRenderingHandler extends CollaborationRenderingHandler { + + @Subscribe + public void drawStrings(DrawStringsEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + DrawStringEvent[] events = event.getObjects(); + DrawableString[] strings = new DrawableString[events.length]; + for (int i = 0; i < events.length; ++i) { + strings[i] = events[i].getDrawableString(); + if (events[i].getFontId() > -1) { + strings[i].font = dataManager.getRenderableObject( + events[i].getFontId(), IFont.class); + } + } + try { + target.drawStrings(strings); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + @Subscribe + public void createFont(CreateFontEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + int fontId = event.getObjectId(); + IFont font = null; + if (event.getFontData() != null) { + try { + File fontFile = File.createTempFile(event.getFontName(), null); + FileUtil.bytes2File(event.getFontData(), fontFile); + font = target.initializeFont(fontFile, event.getFontSize(), + event.getFontStyle()); + } catch (IOException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error creating font from file", e); + } + } else { + font = target.initializeFont(event.getFontName(), + event.getFontSize(), event.getFontStyle()); + } + font.setMagnification(event.getMagnification()); + font.setSmoothing(event.isSmoothing()); + font.setScaleFont(event.isScaleFont()); + dataManager.putRenderableObject(fontId, font); + } + + @Subscribe + public void updateFont(UpdateFontDataEvent event) { + IFont font = dataManager.getRenderableObject(event.getObjectId(), + IFont.class); + if (font != null) { + if (event.getScaleOnMagnify() != null) { + font.setMagnification(event.getMagnification(), + event.getScaleOnMagnify()); + } else { + font.setMagnification(event.getMagnification()); + } + font.setSmoothing(event.getSmoothing()); + font.setScaleFont(event.getScaleFont()); + } + } + + @Subscribe + public void disposeFont(IFont font) { + font.dispose(); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingEvent.java new file mode 100644 index 0000000000..4e33e9dccc --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingEvent.java @@ -0,0 +1,132 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.telestrator; + +import java.util.List; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 3, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class CollaborationDrawingEvent { + + public static enum CollaborationEventType { + DRAW, ERASE, REDO, UNDO, CLEAR, LOCK_USERS, UNLOCK_USERS, CLEAR_ALL, NEW_USER_ARRIVED; + } + + @DynamicSerializeElement + private int displayId; + + @DynamicSerializeElement + private List coordinates; + + @DynamicSerializeElement + private UserId userName; + + @DynamicSerializeElement + private CollaborationEventType type; + + public CollaborationDrawingEvent() { + + } + + public CollaborationDrawingEvent(int displayId) { + this.displayId = displayId; + } + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the coordinates + */ + public List getCoordinates() { + return coordinates; + } + + /** + * @param coordinates + * the coordinates to set + */ + public void setCoordinates(List coordinates) { + this.coordinates = coordinates; + } + + /** + * @return the userName + */ + public UserId getUserName() { + return userName; + } + + /** + * @param userName + * the userName to set + */ + public void setUserName(UserId userName) { + this.userName = userName; + } + + /** + * @return the type + */ + public CollaborationEventType getType() { + return type; + } + + /** + * @param type + * the type to set + */ + public void setType(CollaborationEventType type) { + this.type = type; + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingResource.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingResource.java new file mode 100644 index 0000000000..d51c57a9bc --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingResource.java @@ -0,0 +1,442 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.telestrator; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.data.SessionContainer; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingEvent.CollaborationEventType; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; +import com.raytheon.uf.viz.drawing.DrawingToolLayer; +import com.raytheon.uf.viz.drawing.DrawingToolLayer.DrawMode; +import com.raytheon.uf.viz.remote.graphics.DispatchGraphicsTarget; +import com.raytheon.viz.ui.input.EditableManager; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Resource that uses DrawingToolLayer to render drawn data for multiple users + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 23, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationDrawingResource extends + AbstractVizResource { + + private SessionContainer container; + + private UserId myUser; + + private Map layerMap; + + private CollaborationDrawingUIManager manager; + + private boolean lockingDrawing = false; + + /** + * @param resourceData + * @param loadProperties + */ + public CollaborationDrawingResource( + CollaborationDrawingResourceData resourceData, + LoadProperties loadProperties) throws VizException { + super(resourceData, loadProperties); + container = SharedDisplaySessionMgr.getSessionContainer(resourceData + .getSessionId()); + if (container == null) { + throw new VizException("Could not find container for sessionId: " + + resourceData.getSessionId()); + } + + myUser = container.getSession().getUserID(); + layerMap = new HashMap(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#initInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget) + */ + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + EditableManager.makeEditable(this, true); + if (layerMap == null) { + layerMap = new HashMap(); + } + + OutlineCapability outline = getCapability(OutlineCapability.class); + outline.setLineStyle(LineStyle.SOLID); + outline.setOutlineWidth(4); + outline.setSuppressingMenuItems(true); + + ColorableCapability colorable = getCapability(ColorableCapability.class); + colorable.setSuppressingMenuItems(true); + + if (isSessionLeader()) { + CollaborationDrawingEvent event = new CollaborationDrawingEvent( + resourceData.getDisplayId()); + event.setUserName(myUser); + event.setType(CollaborationEventType.CLEAR_ALL); + sendEvent(event); + } + + manager = new CollaborationDrawingUIManager(this); + container.getSession().registerEventHandler(this); + + getDrawingLayerFor(getMyUser()).setDrawMode( + resourceData.getResourceMode()); + setLockingDrawing(resourceData.isLocking()); + + if (!isSessionLeader()) { + CollaborationDrawingEvent event = new CollaborationDrawingEvent( + resourceData.getDisplayId()); + event.setUserName(getMyUser()); + event.setType(CollaborationEventType.NEW_USER_ARRIVED); + sendEvent(event); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#paintInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + if (target instanceof DispatchGraphicsTarget) { + // Ensure we paint to our own target only + target = ((DispatchGraphicsTarget) target).getWrappedObject(); + } + + OutlineCapability outline = getCapability(OutlineCapability.class); + + synchronized (layerMap) { + for (UserId user : layerMap.keySet()) { + DrawingToolLayer layer = layerMap.get(user); + if (layer != null) { + layer.setEraserWidth(16); // Configure? + layer.setLineStyle(outline.getLineStyle()); + layer.setLineWidth(outline.getOutlineWidth()); + layer.setColor(container.getColorManager() + .getColorFromUser(user)); + layer.paint(target, paintProps); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#disposeInternal() + */ + @Override + protected void disposeInternal() { + container.getSession().unregisterEventHandler(this); + disposeLayers(); + layerMap.clear(); + layerMap = null; + + manager.dispose(); + } + + private void disposeLayers() { + for (DrawingToolLayer layer : layerMap.values()) { + layer.dispose(); + } + } + + /** + * @return the myUser + */ + public UserId getMyUser() { + return myUser; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.core.rsc.IVizResource#getName() + */ + @Override + public String getName() { + return "Telestrator Drawing Tool"; + } + + /** + * Get the DrawingToolLayer object associated with the user, one will be + * created if none exists + * + * @param user + * @return + */ + public DrawingToolLayer getDrawingLayerFor(UserId user) { + if (layerMap != null) { + synchronized (layerMap) { + DrawingToolLayer layer = layerMap.get(user); + if (layer == null) { + if (user == myUser) { + layer = new CollaborationDrawingToolLayer( + descriptor.getGridGeometry(), this); + } else { + layer = new DrawingToolLayer( + descriptor.getGridGeometry()); + } + layerMap.put(user, layer); + } + return layer; + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#project(org.opengis. + * referencing.crs.CoordinateReferenceSystem) + */ + @Override + public void project(CoordinateReferenceSystem crs) throws VizException { + if (layerMap != null) { + synchronized (layerMap) { + for (DrawingToolLayer layer : layerMap.values()) { + layer.reproject(descriptor.getGridGeometry()); + } + } + } + } + + /** + * @return + */ + public boolean isSessionLeader() { + return container.getSession().getCurrentSessionLeader().equals(myUser); + } + + /** + * @return + */ + public boolean isLockingDrawing() { + return lockingDrawing; + } + + public void setLockingDrawing(boolean lockingDrawing) { + if (this.lockingDrawing != lockingDrawing) { + resourceData.setLocking(lockingDrawing); + this.lockingDrawing = lockingDrawing; + if (isSessionLeader()) { + CollaborationDrawingEvent event = new CollaborationDrawingEvent( + resourceData.getDisplayId()); + event.setUserName(myUser); + event.setType(lockingDrawing ? CollaborationEventType.LOCK_USERS + : CollaborationEventType.UNLOCK_USERS); + sendEvent(event); + } + } + } + + /** + * Checks if this resource is able to tellestrate given its state + * + * @return + */ + public boolean canTellestrate() { + return getCapability(EditableCapability.class).isEditable() + && (isSessionLeader() || isLockingDrawing() == false); + } + + @Subscribe + public void participantChanged(IVenueParticipantEvent event) { + UserId user = event.getParticipant(); + switch (event.getEventType()) { + case DEPARTED: + synchronized (layerMap) { + DrawingToolLayer layer = layerMap.remove(user); + if (layer != null) { + layer.dispose(); + issueRefresh(); + } + } + break; + default: + break; + } + } + + @Subscribe + public void handleDrawEvent(CollaborationDrawingEvent event) { + UserId user = event.getUserName(); + if (event.getDisplayId() != resourceData.getDisplayId() + || user.equals(myUser)) { + // Early exit case, don't process my own events twice + issueRefresh(); + return; + } + + synchronized (layerMap) { + DrawingToolLayer layer = getDrawingLayerFor(user); + List points = event.getCoordinates(); + switch (event.getType()) { + case CLEAR: + layer.clear(); + break; + case LOCK_USERS: + // lock + setLockingDrawing(true); + break; + case UNLOCK_USERS: + // unlock + setLockingDrawing(false); + break; + case DRAW: + layer.setDrawMode(DrawMode.DRAW); + if (points != null && points.size() > 0) { + for (Coordinate c : points) { + layer.addCoordinate(c); + } + layer.doneDrawing(); + } + break; + case ERASE: + layer.setDrawMode(DrawMode.ERASE); + if (points != null && points.size() > 0) { + for (Coordinate c : points) { + layer.addCoordinate(c); + } + layer.doneErasing(); + IRenderableDisplay display = descriptor + .getRenderableDisplay(); + layer.processErase(display.getExtent(), display.getBounds()); + } + break; + case REDO: + layer.redo(); + break; + case UNDO: + layer.undo(); + break; + case CLEAR_ALL: + disposeLayers(); + break; + case NEW_USER_ARRIVED: + CollaborationDrawingToolLayer myLayer = (CollaborationDrawingToolLayer) getDrawingLayerFor(getMyUser()); + InitialCollaborationData dataBundle = new InitialCollaborationData( + getMyUser(), resourceData.getDisplayId(), + isSessionLeader(), isLockingDrawing(), myLayer); + sendEventToUser(dataBundle, event.getUserName()); + break; + default: + break; + } + } + issueRefresh(); + } + + @Subscribe + public void initialDataReceived(InitialCollaborationData dataBundle) { + if (resourceData.getDisplayId() == dataBundle.getDisplayId()) { + DrawingToolLayer layer = getDrawingLayerFor(dataBundle + .getUserName()); + if (layer != null) { + layer.rebuildLayer(dataBundle.getCurrrentData(), + dataBundle.getUndoData(), dataBundle.getRedoData()); + } + if (dataBundle.isSessionLeader()) { + setLockingDrawing(dataBundle.isDrawingLocked()); + } + issueRefresh(); + } + } + + public void sendEvent(Object event) { + try { + container.getSession().sendObjectToVenue(event); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + public void sendEventToUser(Object event, UserId user) { + try { + container.getSession().sendObjectToPeer(user, event); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + /** + * @return the container + */ + public SessionContainer getContainer() { + return container; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#okToUnload() + */ + @Override + public boolean okToUnload() { + // Though I hate this methods exists, it serves its purpose + return false; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingResourceData.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingResourceData.java new file mode 100644 index 0000000000..7c2948b7e5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingResourceData.java @@ -0,0 +1,167 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.telestrator; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; + +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.drawing.DrawingToolLayer.DrawMode; + +/** + * Resource data for the CollaborationDrawingResource + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 23, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class CollaborationDrawingResourceData extends AbstractResourceData { + + @XmlAttribute + private String sessionId; + + @XmlAttribute + private int displayId; + + @XmlElement + private DrawMode resourceMode = DrawMode.NONE; + + @XmlAttribute + private boolean locking = false; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#construct(com.raytheon + * .uf.viz.core.rsc.LoadProperties, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + @Override + public CollaborationDrawingResource construct( + LoadProperties loadProperties, IDescriptor descriptor) + throws VizException { + return new CollaborationDrawingResource(this, loadProperties); + } + + /** + * @return the sessionId + */ + public String getSessionId() { + return sessionId; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + /** + * @return the resourceMode + */ + public DrawMode getResourceMode() { + return resourceMode; + } + + /** + * @param resourceMode + * the resourceMode to set + */ + public void setResourceMode(DrawMode resourceMode) { + this.resourceMode = resourceMode; + } + + /** + * @return the locking + */ + public boolean isLocking() { + return locking; + } + + /** + * @param locking + * the locking to set + */ + public void setLocking(boolean locking) { + this.locking = locking; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractResourceData#update(java.lang.Object + * ) + */ + @Override + public void update(Object updateData) { + + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingToolLayer.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingToolLayer.java new file mode 100644 index 0000000000..da2a48347e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingToolLayer.java @@ -0,0 +1,193 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.telestrator; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Stack; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingEvent.CollaborationEventType; +import com.raytheon.uf.viz.drawing.DrawingToolLayer; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; + +/** + * Extension of DrawingToolLayer that forwards events for other participants to + * keep in sync + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 24, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationDrawingToolLayer extends DrawingToolLayer { + + private CollaborationDrawingResource resource; + + private List coordinates = new ArrayList(); + + /** + * @param targetGeometry + */ + public CollaborationDrawingToolLayer(GeneralGridGeometry targetGeometry, + CollaborationDrawingResource resource) { + super(targetGeometry); + this.resource = resource; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.drawing.DrawingToolLayer#setDrawMode(com.raytheon + * .uf.viz.drawing.DrawingToolLayer.DrawMode) + */ + @Override + public void setDrawMode(DrawMode drawMode) { + super.setDrawMode(drawMode); + resource.getResourceData().setResourceMode(drawMode); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.drawing.DrawingToolLayer#addCoordinate(com.vividsolutions + * .jts.geom.Coordinate) + */ + @Override + public void addCoordinate(Coordinate coord) { + super.addCoordinate(coord); + coordinates.add(coord); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolLayer#doneDrawing() + */ + @Override + public void doneDrawing() { + super.doneDrawing(); + sendCoordinateEvent(CollaborationEventType.DRAW); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolLayer#doneErasing() + */ + @Override + public void doneErasing() { + super.doneErasing(); + sendCoordinateEvent(CollaborationEventType.ERASE); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolLayer#undo() + */ + @Override + public void undo() { + super.undo(); + sendSimpleEvent(CollaborationEventType.UNDO); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolLayer#redo() + */ + @Override + public void redo() { + super.redo(); + sendSimpleEvent(CollaborationEventType.REDO); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolLayer#clear() + */ + @Override + public void clear() { + super.clear(); + sendSimpleEvent(CollaborationEventType.CLEAR); + } + + private void sendCoordinateEvent(CollaborationEventType type) { + CollaborationDrawingEvent event = new CollaborationDrawingEvent( + resource.getResourceData().getDisplayId()); + event.setType(type); + event.setUserName(resource.getMyUser()); + event.setCoordinates(new ArrayList(coordinates)); + resource.sendEvent(event); + coordinates.clear(); + } + + private void sendSimpleEvent(CollaborationEventType type) { + CollaborationDrawingEvent event = new CollaborationDrawingEvent( + resource.getResourceData().getDisplayId()); + event.setType(type); + event.setUserName(resource.getMyUser()); + resource.sendEvent(event); + } + + public Stack> getUndoStack() { + Stack> data = new Stack>(); + synchronized (currentData) { + for (StackFrame undoFrame : undoStack) { + data.push(undoFrame.geometries); + } + } + return data; + } + + public Stack> getRedoStack() { + Stack> data = new Stack>(); + synchronized (currentData) { + for (StackFrame redoFrame : redoStack) { + data.push(redoFrame.geometries); + } + } + return data; + } + + public Collection getCurrentData() { + Collection data = new ArrayList(); + synchronized (currentData) { + data.addAll(currentData.geometries); + } + return data; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingUIManager.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingUIManager.java new file mode 100644 index 0000000000..363750d360 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/CollaborationDrawingUIManager.java @@ -0,0 +1,247 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.telestrator; + +import org.eclipse.swt.widgets.Shell; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer.RemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.ActivateRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.DisposeRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.ReprojectRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.event.RenderFrameEvent; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingEvent.CollaborationEventType; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; +import com.raytheon.uf.viz.drawing.DrawingToolLayer; +import com.raytheon.uf.viz.drawing.DrawingToolLayer.DrawMode; +import com.raytheon.uf.viz.drawing.DrawingToolUIManager; +import com.raytheon.uf.viz.remote.graphics.events.rendering.BeginFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * UI Manager for the CollaborationDrawingResource, handles mouse input and + * opens the toolbar. Registers and listens for events on the event bus so that + * drawing can be stopped if zooming, panning, dispose, swap, or scale change + * occurs (to prevent skewing of the drawing). + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 23, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationDrawingUIManager extends DrawingToolUIManager + implements IResourceDataChanged { + + private CollaborationDrawingResource resource; + + private static final int NO_ACTIVE_DISPLAY = -1; + + public CollaborationDrawingUIManager(CollaborationDrawingResource resource) { + super(resource.getDrawingLayerFor(resource.getMyUser()), resource + .getResourceContainer()); + this.resource = resource; + resource.getResourceData().addChangeListener(this); + resource.getContainer().getSession().registerEventHandler(this); + } + + /** + * Drawing event, used for when the leader locks the collaborators from + * drawing + * + * @param event + */ + @Subscribe + public void handleDrawingEvent(CollaborationDrawingEvent event) { + int displayId = getDisplayId(); + if (event.getDisplayId() == displayId) { + if (event.getType() == CollaborationEventType.LOCK_USERS) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + Shell shell = getCurrentShell(); + if (shell != null) { + clearCursor(shell); + } + } + }); + finishDrawing(); + } else if (event.getType() == CollaborationEventType.UNLOCK_USERS) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + if (EditorUtil.getActiveEditor() instanceof AbstractEditor == false) { + Shell shell = getCurrentShell(); + if (shell != null) { + updateCursor(getCurrentShell()); + } + } + } + }); + } + } + } + + /** + * Dispose event, used for when the leader unshares the map + * + * @param event + */ + @Subscribe + public void handleDisposeEvent(DisposeRemoteDisplay event) { + int displayId = getDisplayId(); + if (event.getDisplayId() == displayId) { + finishDrawing(); + } + } + + /** + * Reproject event, used when the map scale changes + * + * @param event + */ + @Subscribe + public void handleReprojectEvent(ReprojectRemoteDisplay event) { + int displayId = getDisplayId(); + if (event.getDisplayId() == displayId) { + finishDrawing(); + } + } + + /** + * Render frame event, used for zoom/pan + * + * @param event + */ + @Subscribe + public void handleRenderFrameEvent(RenderFrameEvent event) { + int displayId = getDisplayId(); + for (IRenderEvent ev : event.getRenderEvents()) { + if (ev instanceof BeginFrameEvent) { + BeginFrameEvent bfe = (BeginFrameEvent) ev; + if (bfe.getExtent() != null || bfe.getBounds() != null + && bfe.getDisplayId() == displayId + || displayId == NO_ACTIVE_DISPLAY) { + finishDrawing(); + } + } + } + } + + @Subscribe + public void handleActivateDisplayEvent(ActivateRemoteDisplay event) { + int displayId = getDisplayId(); + if (event.getDisplayId() != displayId) { + finishDrawing(); + } + } + + /** + * Gets the display id of the current display. This will make sure that the + * event occurred on the display that we are currently drawing on. + * + * @return + */ + private int getDisplayId() { + RemoteDisplay display = resource.getContainer().getDisplayContainer() + .getActiveDisplay(); + if (display != null) { + return display.getDisplayId(); + } else { + // event to unshared editor, so that active display doesn't + // exist + return NO_ACTIVE_DISPLAY; + } + } + + /** + * Emulate the fact that drawing should be finished. This will be called + * from numerous places for when the user "should" stop drawing to prevent + * drawing errors + */ + private void finishDrawing() { + // 0 for all values is fine since it will just return immediately + handleMouseUp(0, 0, 0); + setHandlingInput(false); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolUIManager#dispose() + */ + @Override + public void dispose() { + resource.getResourceData().removeChangeListener(this); + resource.getContainer().getSession().unregisterEventHandler(this); + super.dispose(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.drawing.DrawingToolUIManager#canTellestrate(int) + */ + @Override + protected boolean canTellestrate(int mouseButton) { + return super.canTellestrate(mouseButton) && resource.canTellestrate(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.IResourceDataChanged#resourceChanged(com + * .raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType, + * java.lang.Object) + */ + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.CAPABILITY + && object instanceof EditableCapability) { + EditableCapability editable = (EditableCapability) object; + if (editable.isEditable() == false) { + DrawingToolLayer layer = resource.getDrawingLayerFor(resource + .getMyUser()); + layer.setDrawMode(DrawMode.NONE); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + updateCursor(getCurrentShell()); + } + }); + } + } + resource.issueRefresh(); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/InitialCollaborationData.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/InitialCollaborationData.java new file mode 100644 index 0000000000..3f7f68022d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/rsc/telestrator/InitialCollaborationData.java @@ -0,0 +1,147 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.rsc.telestrator; + +import java.util.Collection; +import java.util.Stack; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.vividsolutions.jts.geom.Geometry; + +/** + * Holds all drawing data for a user, which is sent to new user upon joining a + * telestrator session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 11, 2012            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +@DynamicSerialize +public class InitialCollaborationData { + + @DynamicSerializeElement + private int displayId; + + @DynamicSerializeElement + private UserId userName; + + @DynamicSerializeElement + private boolean sessionLeader; + + @DynamicSerializeElement + private boolean drawingLocked; + + @DynamicSerializeElement + private Collection currrentData; + + @DynamicSerializeElement + private Stack> redoData; + + @DynamicSerializeElement + private Stack> undoData; + + /** + * It is recommended that this constructor only be used by dynamic + * serialize. + */ + public InitialCollaborationData() { + + } + + public InitialCollaborationData(UserId userName, int displayId, + boolean sessionLeader, boolean drawingLocked, + CollaborationDrawingToolLayer layer) { + this.userName = userName; + this.displayId = displayId; + this.sessionLeader = sessionLeader; + this.drawingLocked = drawingLocked; + this.currrentData = layer.getCurrentData(); + this.undoData = layer.getUndoStack(); + this.redoData = layer.getRedoStack(); + } + + public UserId getUserName() { + return userName; + } + + public void setUserName(UserId userName) { + this.userName = userName; + } + + public Collection getCurrrentData() { + return currrentData; + } + + public void setCurrrentData(Collection currrentData) { + this.currrentData = currrentData; + } + + public Stack> getRedoData() { + return redoData; + } + + public void setRedoData(Stack> redoData) { + this.redoData = redoData; + } + + public Stack> getUndoData() { + return undoData; + } + + public void setUndoData(Stack> undoData) { + this.undoData = undoData; + } + + public int getDisplayId() { + return displayId; + } + + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + public boolean isSessionLeader() { + return sessionLeader; + } + + public void setSessionLeader(boolean sessionLeader) { + this.sessionLeader = sessionLeader; + } + + public boolean isDrawingLocked() { + return drawingLocked; + } + + public void setDrawingLocked(boolean drawingLocked) { + this.drawingLocked = drawingLocked; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java new file mode 100644 index 0000000000..a23710c7cd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/CollaborationObjectEventStorage.java @@ -0,0 +1,491 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.storage; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.ByteArrayEntity; + +import com.raytheon.uf.common.comm.HttpClient; +import com.raytheon.uf.common.comm.HttpClient.HttpClientResponse; +import com.raytheon.uf.common.comm.NetworkStatistics; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.collaboration.comm.compression.CompressionUtil; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.provider.session.PeerToPeerCommHelper; +import com.raytheon.uf.viz.remote.graphics.Dispatcher; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Class responsible for object event storage. Will persist/retrieve objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 20, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationObjectEventStorage implements + IObjectEventPersistance, IObjectEventRetrieval { + + private static NetworkStatistics stats = com.raytheon.uf.viz.collaboration.comm.Activator + .getDefault().getNetworkStats(); + + public static IObjectEventPersistance createPersistanceObject( + ISharedDisplaySession session, Dispatcher dispatcher) + throws CollaborationException { + CollaborationObjectEventStorage persistance = new CollaborationObjectEventStorage( + session, dispatcher.getDispatcherId()); + persistance.createFolder(URI.create(persistance.sessionDataURL)); + persistance.sessionDataURL += persistance.displayId + "/"; + persistance.createFolder(URI.create(persistance.sessionDataURL)); + return persistance; + } + + public static IObjectEventRetrieval createRetrievalObject( + ISharedDisplaySession session, int displayId) { + CollaborationObjectEventStorage persistance = new CollaborationObjectEventStorage( + session, displayId); + persistance.sessionDataURL += persistance.displayId + "/"; + return persistance; + } + + private String sessionDataURL; + + private HttpClient client; + + private int displayId; + + private CollaborationObjectEventStorage(ISharedDisplaySession session, + int displayId) { + this.displayId = displayId; + this.client = HttpClient.getInstance(); + this.sessionDataURL = PeerToPeerCommHelper.getCollaborationHttpServer(); + this.sessionDataURL += session.getSessionId() + "/"; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventPersistance + * #persistEvent + * (com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent) + */ + @Override + public IPersistedEvent persistEvent(AbstractDispatchingObjectEvent event) + throws CollaborationException { + if (event instanceof ICreationEvent) { + createFolder(String.valueOf(event.getObjectId())); + } else if (event instanceof DisposeObjectEvent) { + // Do not delete anything off the server, users may still be + // retrieving data off the server if they have not yet processed all + // the messages and everything gets deleted when the session is + // closed anyway. + // deleteResource(URI.create(sessionDataURL + event.getObjectId() + // + "/")); + CollaborationWrappedEvent wrapped = new CollaborationWrappedEvent(); + wrapped.setDisplayId(displayId); + wrapped.setEvent(event); + return wrapped; + } + + try { + CollaborationHttpPersistedEvent wrapped = new CollaborationHttpPersistedEvent(); + String objectPath = event.getObjectId() + "/" + + event.getClass().getName() + ".obj"; + String eventObjectURL = sessionDataURL + objectPath; + HttpPut put = new HttpPut(eventObjectURL); + + CollaborationHttpPersistedObject persistObject = new CollaborationHttpPersistedObject(); + persistObject.persistTime = System.currentTimeMillis(); + persistObject.event = event; + byte[] toPersist = CompressionUtil.compress(SerializationUtil + .transformToThrift(persistObject)); + stats.log(event.getClass().getSimpleName(), toPersist.length, 0); + put.setEntity(new ByteArrayEntity(toPersist)); + HttpClientResponse response = executeRequest(put); + if (isSuccess(response.code) == false) { + throw new CollaborationException( + "Error uploading event object (" + event.getObjectId() + + ") to server @ " + eventObjectURL + " : " + + new String(response.data)); + } + wrapped.setDisplayId(displayId); + wrapped.setResourcePath(objectPath); + return wrapped; + } catch (CollaborationException e) { + throw e; + } catch (Exception e) { + throw new CollaborationException(e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventPersistance + * #dispose() + */ + @Override + public void dispose() throws CollaborationException { + deleteResource(URI.create(sessionDataURL)); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval + * #retrieveEvent + * (com.raytheon.uf.viz.collaboration.ui.role.event.IPersistedEvent) + */ + @Override + public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event) + throws CollaborationException { + if (event instanceof CollaborationHttpPersistedEvent) { + CollaborationHttpPersistedObject object = retreiveStoredObject((CollaborationHttpPersistedEvent) event); + if (object == null) { + // No object available + return null; + } else if (object.event != null) { + stats.log(object.event.getClass().getSimpleName(), 0, + object.dataSize); + return object.event; + } else { + throw new CollaborationException( + "Unable to deserialize persisted event into event object"); + } + } else if (event instanceof CollaborationWrappedEvent) { + return ((CollaborationWrappedEvent) event).getEvent(); + } else { + throw new CollaborationException( + "Unable to retreieve event for object: " + event); + } + } + + private CollaborationHttpPersistedObject retreiveStoredObject( + CollaborationHttpPersistedEvent event) + throws CollaborationException { + String objectPath = event.getResourcePath(); + HttpGet get = new HttpGet(sessionDataURL + objectPath); + HttpClientResponse response = executeRequest(get); + if (isSuccess(response.code)) { + try { + CollaborationHttpPersistedObject dataObject = (CollaborationHttpPersistedObject) SerializationUtil + .transformFromThrift(CompressionUtil + .uncompress(response.data)); + if (dataObject != null) { + dataObject.dataSize = response.data.length; + } + return dataObject; + } catch (SerializationException e) { + throw new CollaborationException(e); + } + } else if (isNotExists(response.code)) { + // Object was deleted + return null; + } else { + throw new CollaborationException("Error retrieving object from " + + objectPath + " : " + new String(response.data)); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.role.event.IObjectEventRetrieval + * #retrieveObjectEvents(int) + */ + @Override + public AbstractDispatchingObjectEvent[] retrieveObjectEvents(int objectId) + throws CollaborationException { + String objectPath = objectId + "/"; + HttpGet get = new HttpGet(sessionDataURL + objectPath); + HttpClientResponse response = executeRequest(get); + if (isSuccess(response.code) == false) { + if (isNotExists(response.code)) { + return new AbstractDispatchingObjectEvent[0]; + } + throw new CollaborationException("Error retrieving object (" + + objectId + ") events, received code: " + response.code); + } + CollaborationHttpPersistedEvent event = new CollaborationHttpPersistedEvent(); + List objectEvents = new ArrayList(); + // parse out links of objects + String htmlStr = new String(response.data); + int searchIdx = 0; + String searchStrStart = ""; + int searchStrLen = searchStrStart.length(); + while (searchIdx > -1) { + int previousIdx = searchIdx; + int foundAt = htmlStr.indexOf(searchStrStart, searchIdx); + // reset searchIdx to -1 until found + searchIdx = -1; + if (foundAt > previousIdx) { + foundAt += searchStrLen; + int endsAt = htmlStr.indexOf(searchStrEnd, foundAt); + if (endsAt > foundAt) { + String object = htmlStr.substring(foundAt, endsAt); + if (object.endsWith(objectEnding)) { + event.setResourcePath(objectPath + object); + CollaborationHttpPersistedObject eventObject = retreiveStoredObject(event); + if (eventObject != null) { + objectEvents.add(eventObject); + } else { + // Object was deleted, abort + return new AbstractDispatchingObjectEvent[0]; + } + } + searchIdx = endsAt + 1; + } + } + } + + // Sort by creation time + Collections.sort(objectEvents, + new Comparator() { + @Override + public int compare(CollaborationHttpPersistedObject o1, + CollaborationHttpPersistedObject o2) { + return (int) (o1.persistTime - o2.persistTime); + } + }); + + AbstractDispatchingObjectEvent[] events = new AbstractDispatchingObjectEvent[objectEvents + .size()]; + int i = 0; + for (CollaborationHttpPersistedObject object : objectEvents) { + events[i++] = object.event; + } + + return events; + } + + private void createFolder(String folderPath) throws CollaborationException { + createFolder(URI.create(sessionDataURL + folderPath)); + } + + private void createFolder(URI folderPath) throws CollaborationException { + HttpRequestBase mkcol = new HttpRequestBase() { + @Override + public String getMethod() { + return "MKCOL"; + } + }; + mkcol.setURI(folderPath); + HttpClientResponse rsp = executeRequest(mkcol); + if (isSuccess(rsp.code) == false && isDirExists(rsp.code) == false) { + throw new CollaborationException("Folder creation failed for " + + folderPath + ": " + new String(rsp.data)); + } + } + + private void deleteResource(URI uri) throws CollaborationException { + HttpClientResponse rsp = executeRequest(new HttpDelete(uri)); + // If request was success or resource doesn't exist, we are good + if (isSuccess(rsp.code) == false && isNotExists(rsp.code) == false) { + throw new CollaborationException("Folder creation failed for " + + uri + ": " + new String(rsp.data)); + } + } + + private HttpClientResponse executeRequest(HttpUriRequest request) + throws CollaborationException { + try { + return client.executeRequest(request); + } catch (Exception e) { + throw new CollaborationException(e); + } + } + + private boolean isSuccess(int code) { + return code >= 200 && code < 300; + } + + private boolean isNotExists(int code) { + return code == 404 || code == 410; + } + + private boolean isDirExists(int code) { + return code == 405 || code == 301; + } + + @DynamicSerialize + public static class CollaborationHttpPersistedObject { + + @DynamicSerializeElement + private long persistTime; + + @DynamicSerializeElement + private AbstractDispatchingObjectEvent event; + + private long dataSize; + + /** + * @return the persistTime + */ + public long getPersistTime() { + return persistTime; + } + + /** + * @param persistTime + * the persistTime to set + */ + public void setPersistTime(long persistTime) { + this.persistTime = persistTime; + } + + /** + * @return the event + */ + public AbstractDispatchingObjectEvent getEvent() { + return event; + } + + /** + * @param event + * the event to set + */ + public void setEvent(AbstractDispatchingObjectEvent event) { + this.event = event; + } + + } + + @DynamicSerialize + public static class CollaborationHttpPersistedEvent implements + IPersistedEvent { + + @DynamicSerializeElement + private int displayId; + + @DynamicSerializeElement + private String resourcePath; + + /** + * @return the resourceURL + */ + public String getResourcePath() { + return resourcePath; + } + + /** + * @param resourceURL + * the resourceURL to set + */ + public void setResourcePath(String resourceURL) { + this.resourcePath = resourceURL; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.role.dataprovider.event. + * IPersistedEvent#getDisplayId() + */ + @Override + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + } + + @DynamicSerialize + public static class CollaborationWrappedEvent implements IPersistedEvent { + + @DynamicSerializeElement + private int displayId; + + @DynamicSerializeElement + private AbstractDispatchingObjectEvent event; + + /** + * @return the event + */ + public AbstractDispatchingObjectEvent getEvent() { + return event; + } + + /** + * @param event + * the event to set + */ + public void setEvent(AbstractDispatchingObjectEvent event) { + this.event = event; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.role.dataprovider.event. + * IPersistedEvent#getDisplayId() + */ + @Override + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IObjectEventPersistance.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IObjectEventPersistance.java new file mode 100644 index 0000000000..fe9f86fcad --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IObjectEventPersistance.java @@ -0,0 +1,48 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.storage; + +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Interface for persisting remote object events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 20, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface IObjectEventPersistance { + + public IPersistedEvent persistEvent(AbstractDispatchingObjectEvent event) + throws CollaborationException; + + public void dispose() throws CollaborationException; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IObjectEventRetrieval.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IObjectEventRetrieval.java new file mode 100644 index 0000000000..fd21da594c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IObjectEventRetrieval.java @@ -0,0 +1,51 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.storage; + +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Interface for retrieving IPersistedEvents and constructing an object from id + * based on previous events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 20, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface IObjectEventRetrieval { + + public AbstractDispatchingObjectEvent retrieveEvent(IPersistedEvent event) + throws CollaborationException; + + public AbstractDispatchingObjectEvent[] retrieveObjectEvents(int objectId) + throws CollaborationException; + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IPersistedEvent.java b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IPersistedEvent.java new file mode 100644 index 0000000000..8b50b12ed3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.display/src/com/raytheon/uf/viz/collaboration/display/storage/IPersistedEvent.java @@ -0,0 +1,44 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.display.storage; + +/** + * Interface for distinguishing events that are persisted and should be + * retrieved + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 20, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface IPersistedEvent { + + public int getDisplayId(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.feature/.project b/cave/com.raytheon.uf.viz.collaboration.feature/.project new file mode 100644 index 0000000000..b0f849e119 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.feature/.project @@ -0,0 +1,17 @@ + + + com.raytheon.uf.viz.collaboration.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.feature/build.properties b/cave/com.raytheon.uf.viz.collaboration.feature/build.properties new file mode 100644 index 0000000000..64f93a9f0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.feature/feature.xml b/cave/com.raytheon.uf.viz.collaboration.feature/feature.xml new file mode 100644 index 0000000000..b25214d3b1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.feature/feature.xml @@ -0,0 +1,153 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/.classpath b/cave/com.raytheon.uf.viz.collaboration.pointdata/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/.project b/cave/com.raytheon.uf.viz.collaboration.pointdata/.project new file mode 100644 index 0000000000..6ded4aed68 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.pointdata + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.pointdata/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..b485d5b5e6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Fri Apr 27 12:09:01 CDT 2012 +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/cave/com.raytheon.uf.viz.collaboration.pointdata/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.pointdata/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..cebe041fcd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/META-INF/MANIFEST.MF @@ -0,0 +1,16 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Collaboration Point data +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.pointdata;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.pointdata.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Require-Bundle: org.eclipse.core.runtime, + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.viz.collaboration.display;bundle-version="1.0.0", + com.raytheon.uf.viz.remote.graphics;bundle-version="1.0.0", + com.raytheon.viz.pointdata;bundle-version="1.12.1174", + com.google.guava;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/build.properties b/cave/com.raytheon.uf.viz.collaboration.pointdata/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/plugin.xml b/cave/com.raytheon.uf.viz.collaboration.pointdata/plugin.xml new file mode 100644 index 0000000000..f17045f9e7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/plugin.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/Activator.java b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/Activator.java new file mode 100644 index 0000000000..fad93d1a79 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/Activator.java @@ -0,0 +1,30 @@ +package com.raytheon.uf.viz.collaboration.pointdata; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/DispatchingPointImageExtension.java b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/DispatchingPointImageExtension.java new file mode 100644 index 0000000000..0704f80bb1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/DispatchingPointImageExtension.java @@ -0,0 +1,117 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.pointdata.image; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.DispatchGraphicsTarget; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingImage; +import com.raytheon.viz.pointdata.drawables.IPointImageExtension; + +/** + * Dispatching extension for point images + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DispatchingPointImageExtension extends + GraphicsExtension implements + IPointImageExtension { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.pointdata.drawables.IPointImageExtension#drawPointImages + * (com.raytheon.uf.viz.core.drawables.PaintProperties, + * com.raytheon.viz.pointdata.drawables.IPointImageExtension.PointImage[]) + */ + @Override + public void drawPointImages(PaintProperties paintProps, + PointImage... images) throws VizException { + drawPointImages(paintProps, Arrays.asList(images)); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.pointdata.drawables.IPointImageExtension#drawPointImages + * (com.raytheon.uf.viz.core.drawables.PaintProperties, + * java.util.Collection) + */ + @Override + public void drawPointImages(PaintProperties paintProps, + Collection images) throws VizException { + // Dispatch event + DrawPointImagesEvent event = RemoteGraphicsEventFactory.createEvent( + DrawPointImagesEvent.class, target); + event.setAlpha(paintProps.getAlpha()); + event.setPointImages(images); + target.dispatch(event); + + // Extract a non dispatching point image and draw to wrapped target + List extracted = new ArrayList(images.size()); + for (PointImage image : images) { + PointImage pi = new PointImage( + ((DispatchingImage) image.getImage()).getWrappedObject(), + image.getX(), image.getY()); + pi.setWidth(image.getWidth()); + pi.setHeight(image.getHeight()); + pi.setHorizontalAlignment(image.getHorizontalAlignment()); + pi.setVerticalAlignment(image.getVerticalAlignment()); + pi.setSiteId(image.getSiteId()); + extracted.add(pi); + } + + target.getWrappedObject().getExtension(IPointImageExtension.class) + .drawPointImages(paintProps, extracted); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension# + * getCompatibilityValue(com.raytheon.uf.viz.core.IGraphicsTarget) + */ + @Override + public int getCompatibilityValue(DispatchGraphicsTarget target) { + return Compatibilty.TARGET_COMPATIBLE; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/DrawPointImagesEvent.java b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/DrawPointImagesEvent.java new file mode 100644 index 0000000000..5d49b188e1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/DrawPointImagesEvent.java @@ -0,0 +1,198 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.pointdata.image; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; +import com.raytheon.viz.pointdata.drawables.IPointImageExtension.PointImage; + +/** + * Event for drawing a set of point images + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 30, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawPointImagesEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private float alpha = 1.0f; + + @DynamicSerializeElement + private Set images = new HashSet(); + + @DynamicSerializeElement + private Set removals = null; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#createDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + DrawPointImagesEvent diffEvent = (DrawPointImagesEvent) event; + Set additions = new HashSet( + diffEvent.images); + additions.removeAll(images); + Set removals = new HashSet(images); + removals.removeAll(diffEvent.images); + DrawPointImagesEvent diffObject = new DrawPointImagesEvent(); + diffObject.setAlpha(diffEvent.getAlpha()); + if (additions.size() + removals.size() > diffEvent.images.size()) { + // Just do a full replace + diffObject.setRemovals(null); + diffObject.setImages(diffEvent.images); + } else { + diffObject.setImages(additions); + diffObject.setRemovals(removals); + } + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + DrawPointImagesEvent diffObject = (DrawPointImagesEvent) diffEvent; + synchronized (images) { + if (diffObject.removals != null) { + images.removeAll(diffObject.removals); + images.addAll(diffObject.images); + } else { + // Null removals indicates full replaces + images = new HashSet(diffObject.images); + } + } + alpha = diffObject.getAlpha(); + } + + public void setPointImages(Collection images) { + for (PointImage image : images) { + PointImageEvent event = new PointImageEvent(); + event.setPointImage(image); + this.images.add(event); + } + } + + public Set getImagesCopy() { + synchronized (images) { + return new HashSet(images); + } + } + + /** + * @return the removals + */ + public Set getRemovals() { + return removals; + } + + /** + * @param removals + * the removals to set + */ + public void setRemovals(Set removals) { + this.removals = removals; + } + + /** + * @return the images + */ + public Set getImages() { + return images; + } + + /** + * @param images + * the images to set + */ + public void setImages(Set images) { + this.images = images; + } + + /** + * @return the alpha + */ + public float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(float alpha) { + this.alpha = alpha; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DrawPointImagesEvent other = (DrawPointImagesEvent) obj; + if (Float.floatToIntBits(alpha) != Float.floatToIntBits(other.alpha)) + return false; + if (images == null) { + if (other.images != null) + return false; + } else if (!images.equals(other.images)) + return false; + if (removals == null) { + if (other.removals != null) + return false; + } else if (!removals.equals(other.removals)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/PointImageEvent.java b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/PointImageEvent.java new file mode 100644 index 0000000000..3389d3a6e8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/image/PointImageEvent.java @@ -0,0 +1,275 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.pointdata.image; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment; +import com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingImage; +import com.raytheon.viz.pointdata.drawables.IPointImageExtension.PointImage; + +/** + * Event object for drawing a PointImage + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 30, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class PointImageEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private int imageId; + + @DynamicSerializeElement + private double x; + + @DynamicSerializeElement + private double y; + + @DynamicSerializeElement + private Double width; + + @DynamicSerializeElement + private Double height; + + @DynamicSerializeElement + private HorizontalAlignment horizontalAlignment; + + @DynamicSerializeElement + private VerticalAlignment verticalAlignment; + + @DynamicSerializeElement + private String siteId; + + public void setPointImage(PointImage image) { + this.imageId = ((DispatchingImage) image.getImage()).getObjectId(); + this.x = image.getX(); + this.y = image.getY(); + this.width = image.getWidth(); + this.height = image.getHeight(); + this.horizontalAlignment = image.getHorizontalAlignment(); + this.verticalAlignment = image.getVerticalAlignment(); + this.siteId = image.getSiteId(); + } + + /** + * @return the imageId + */ + public int getImageId() { + return imageId; + } + + /** + * @param imageId + * the imageId to set + */ + public void setImageId(int imageId) { + this.imageId = imageId; + } + + /** + * @return the x + */ + public double getX() { + return x; + } + + /** + * @param x + * the x to set + */ + public void setX(double x) { + this.x = x; + } + + /** + * @return the y + */ + public double getY() { + return y; + } + + /** + * @param y + * the y to set + */ + public void setY(double y) { + this.y = y; + } + + /** + * @return the width + */ + public Double getWidth() { + return width; + } + + /** + * @param width + * the width to set + */ + public void setWidth(Double width) { + this.width = width; + } + + /** + * @return the height + */ + public Double getHeight() { + return height; + } + + /** + * @param height + * the height to set + */ + public void setHeight(Double height) { + this.height = height; + } + + /** + * @return the horizontalAlignment + */ + public HorizontalAlignment getHorizontalAlignment() { + return horizontalAlignment; + } + + /** + * @param horizontalAlignment + * the horizontalAlignment to set + */ + public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) { + this.horizontalAlignment = horizontalAlignment; + } + + /** + * @return the verticalAlignment + */ + public VerticalAlignment getVerticalAlignment() { + return verticalAlignment; + } + + /** + * @param verticalAlignment + * the verticalAlignment to set + */ + public void setVerticalAlignment(VerticalAlignment verticalAlignment) { + this.verticalAlignment = verticalAlignment; + } + + /** + * @return the siteId + */ + public String getSiteId() { + return siteId; + } + + /** + * @param siteId + * the siteId to set + */ + public void setSiteId(String siteId) { + this.siteId = siteId; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((height == null) ? 0 : height.hashCode()); + result = prime + * result + + ((horizontalAlignment == null) ? 0 : horizontalAlignment + .hashCode()); + result = prime * result + imageId; + result = prime * result + ((siteId == null) ? 0 : siteId.hashCode()); + result = prime + * result + + ((verticalAlignment == null) ? 0 : verticalAlignment + .hashCode()); + result = prime * result + ((width == null) ? 0 : width.hashCode()); + long temp; + temp = Double.doubleToLongBits(x); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(y); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + PointImageEvent other = (PointImageEvent) obj; + if (height == null) { + if (other.height != null) + return false; + } else if (!height.equals(other.height)) + return false; + if (horizontalAlignment != other.horizontalAlignment) + return false; + if (imageId != other.imageId) + return false; + if (siteId == null) { + if (other.siteId != null) + return false; + } else if (!siteId.equals(other.siteId)) + return false; + if (verticalAlignment != other.verticalAlignment) + return false; + if (width == null) { + if (other.width != null) + return false; + } else if (!width.equals(other.width)) + return false; + if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) + return false; + if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/rendering/PointImageRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/rendering/PointImageRenderingHandler.java new file mode 100644 index 0000000000..eea86f3402 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.pointdata/src/com/raytheon/uf/viz/collaboration/pointdata/rendering/PointImageRenderingHandler.java @@ -0,0 +1,88 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.pointdata.rendering; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.rsc.rendering.CollaborationRenderingHandler; +import com.raytheon.uf.viz.collaboration.pointdata.image.DrawPointImagesEvent; +import com.raytheon.uf.viz.collaboration.pointdata.image.PointImageEvent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IImage; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.viz.pointdata.drawables.IPointImageExtension; +import com.raytheon.viz.pointdata.drawables.IPointImageExtension.PointImage; + +/** + * Class for rending PointImage objects, handles DrawPointImagesEvent events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 30, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class PointImageRenderingHandler extends CollaborationRenderingHandler { + + @Subscribe + public void drawPointImages(DrawPointImagesEvent event) { + IGraphicsTarget target = getGraphicsTarget(); + PaintProperties newProps = new PaintProperties(getPaintProperties()); + newProps.setAlpha(event.getAlpha()); + Set events = event.getImagesCopy(); + List images = new ArrayList(events.size()); + for (PointImageEvent pie : events) { + IImage image = dataManager.getRenderableObject(pie.getImageId(), + IImage.class); + if (image != null) { + PointImage pi = new PointImage(image, pie.getX(), pie.getY()); + pi.setWidth(pie.getWidth()); + pi.setHeight(pie.getHeight()); + pi.setHorizontalAlignment(pie.getHorizontalAlignment()); + pi.setVerticalAlignment(pie.getVerticalAlignment()); + pi.setSiteId(pie.getSiteId()); + images.add(pi); + } + } + + try { + target.getExtension(IPointImageExtension.class).drawPointImages( + newProps, images); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.product.feature/.project b/cave/com.raytheon.uf.viz.collaboration.product.feature/.project new file mode 100644 index 0000000000..084521772e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product.feature/.project @@ -0,0 +1,17 @@ + + + com.raytheon.uf.viz.collaboration.product.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.product.feature/build.properties b/cave/com.raytheon.uf.viz.collaboration.product.feature/build.properties new file mode 100644 index 0000000000..64f93a9f0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.product.feature/feature.xml b/cave/com.raytheon.uf.viz.collaboration.product.feature/feature.xml new file mode 100644 index 0000000000..fb723026b1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product.feature/feature.xml @@ -0,0 +1,252 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.product/.classpath b/cave/com.raytheon.uf.viz.collaboration.product/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.product/.project b/cave/com.raytheon.uf.viz.collaboration.product/.project new file mode 100644 index 0000000000..b61fcfd242 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.product + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.product/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.product/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..7166917541 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Jun 25 15:43:02 CDT 2012 +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/cave/com.raytheon.uf.viz.collaboration.product/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.product/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..ee400575a2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/META-INF/MANIFEST.MF @@ -0,0 +1,13 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Collaboration Product +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.product;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.product.Activator +Bundle-Vendor: RAYTHEON +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.application;bundle-version="1.0.0", + com.raytheon.uf.common.localization;bundle-version="1.12.1174" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy diff --git a/cave/com.raytheon.uf.viz.collaboration.product/build.properties b/cave/com.raytheon.uf.viz.collaboration.product/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.product/collaboration.product b/cave/com.raytheon.uf.viz.collaboration.product/collaboration.product new file mode 100644 index 0000000000..36d3bd2ad8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/collaboration.product @@ -0,0 +1,58 @@ + + + + + + + + + Alert Visualizer + + + +Developed on the Raytheon Visualization Environment (viz) + + + + + + + + -data @user.home/caveData -user @user.home/caveData -clean -component collaboration + -consoleLog + -Xincgc -Xmx256M -Xss2024k -Dosgi.instance.area.readOnly=true -Dosgi.hook.configurators.exclude=org.eclipse.core.runtime.internal.adaptor.EclipseLogHook,org.eclipse.core.runtime.internal.adaptor.EclipseErrorHandler -Dorg.eclipse.update.reconcile=false -Dqpid.dest_syntax=BURL -Dorg.eclipse.update.reconcile=false -XX:MaxPermSize=128m -Dorg.eclipse.ui/KEY_CONFIGURATION_ID=com.raytheon.viz.ui.awips.scheme -Dawips.mode=pypies -Dqpid.dest_syntax=BURL -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false + + + + + + + + + + + + + jdk1.6.0 + jdk1.6.0 + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.product/plugin.xml b/cave/com.raytheon.uf.viz.collaboration.product/plugin.xml new file mode 100644 index 0000000000..e03fc22c07 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/plugin.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/Activator.java b/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/Activator.java new file mode 100644 index 0000000000..877a806b60 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/Activator.java @@ -0,0 +1,50 @@ +package com.raytheon.uf.viz.collaboration.product; + +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.raytheon.uf.viz.collaboration.product"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * 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; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/CollaborationComponent.java b/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/CollaborationComponent.java new file mode 100644 index 0000000000..e0e9ae9425 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/CollaborationComponent.java @@ -0,0 +1,60 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.product; + +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.viz.application.component.IStandaloneComponent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 25, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationComponent implements IStandaloneComponent { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.application.component.IStandaloneComponent#startComponent + * (java.lang.String) + */ + @Override + public Object startComponent(String componentName) throws Exception { + PathManagerFactory.setAdapter(new CollaborationLocalizationAdapter()); + // TODO: + System.out + .println("TODO: Initialize collaboration dialog that creates similar environment as the view in eclipse."); + return null; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/CollaborationLocalizationAdapter.java b/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/CollaborationLocalizationAdapter.java new file mode 100644 index 0000000000..c75a221d11 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.product/src/com/raytheon/uf/viz/collaboration/product/CollaborationLocalizationAdapter.java @@ -0,0 +1,237 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.product; + +import java.io.File; + +import com.raytheon.uf.common.localization.ILocalizationAdapter; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; + +/** + * TODO Mimic CAVELocalizationAdapter! + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationLocalizationAdapter implements ILocalizationAdapter { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#getDirNameForType + * ( + * com.raytheon.uf.common.localization.LocalizationContext.LocalizationType) + */ + @Override + public String getDirNameForType(LocalizationType type) { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#getPath(com. + * raytheon.uf.common.localization.LocalizationContext, java.lang.String) + */ + @Override + public File getPath(LocalizationContext context, String fileName) { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.common.localization.ILocalizationAdapter# + * getLocalizationMetadata + * (com.raytheon.uf.common.localization.LocalizationContext[], + * java.lang.String) + */ + @Override + public ListResponse[] getLocalizationMetadata( + LocalizationContext[] context, String fileName) + throws LocalizationOpFailedException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#retrieve(com + * .raytheon.uf.common.localization.LocalizationFile) + */ + @Override + public void retrieve(LocalizationFile file) + throws LocalizationOpFailedException { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#save(java.io + * .File, com.raytheon.uf.common.localization.LocalizationContext, + * java.lang.String) + */ + @Override + public boolean save(File localFile, LocalizationContext context, + String fileName) throws LocalizationOpFailedException { + // TODO Auto-generated method stub + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#listDirectory + * (com.raytheon.uf.common.localization.LocalizationContext[], + * java.lang.String, boolean, boolean) + */ + @Override + public ListResponse[] listDirectory(LocalizationContext[] context, + String path, boolean recursive, boolean filesOnly) + throws LocalizationOpFailedException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.common.localization.ILocalizationAdapter# + * getLocalSearchHierarchy + * (com.raytheon.uf.common.localization.LocalizationContext + * .LocalizationType) + */ + @Override + public LocalizationContext[] getLocalSearchHierarchy(LocalizationType type) { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#getStaticContexts + * () + */ + @Override + public LocalizationType[] getStaticContexts() { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#getContext(com + * .raytheon.uf.common.localization.LocalizationContext.LocalizationType, + * com + * .raytheon.uf.common.localization.LocalizationContext.LocalizationLevel) + */ + @Override + public LocalizationContext getContext(LocalizationType type, + LocalizationLevel level) { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#delete(java. + * io.File, com.raytheon.uf.common.localization.LocalizationContext, + * java.lang.String) + */ + @Override + public boolean delete(File file, LocalizationContext context, + String fileName) throws LocalizationOpFailedException { + // TODO Auto-generated method stub + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#getContextList + * (com + * .raytheon.uf.common.localization.LocalizationContext.LocalizationLevel) + */ + @Override + public String[] getContextList(LocalizationLevel level) + throws LocalizationOpFailedException { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#getAvailableLevels + * () + */ + @Override + public LocalizationLevel[] getAvailableLevels() { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.localization.ILocalizationAdapter#exists(com.raytheon + * .uf.common.localization.LocalizationFile) + */ + @Override + public boolean exists(LocalizationFile file) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/.classpath b/cave/com.raytheon.uf.viz.collaboration.radar/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/.project b/cave/com.raytheon.uf.viz.collaboration.radar/.project new file mode 100644 index 0000000000..7e145e7f30 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.radar + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.radar/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..88de49aa5c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Thu Apr 12 17:10:20 CDT 2012 +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/cave/com.raytheon.uf.viz.collaboration.radar/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.radar/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..49d59f37e1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/META-INF/MANIFEST.MF @@ -0,0 +1,21 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Radar Collaboration +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.radar;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.radar.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Require-Bundle: org.eclipse.core.runtime, + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.common.dataplugin.radar;bundle-version="1.0.0", + com.raytheon.viz.radar;bundle-version="1.12.1174", + com.raytheon.uf.viz.remote.graphics;bundle-version="1.0.0", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + org.geotools;bundle-version="2.6.4", + com.raytheon.uf.common.colormap;bundle-version="1.12.1174", + com.raytheon.uf.viz.collaboration.display;bundle-version="1.0.0", + com.raytheon.uf.viz.collaboration.comm;bundle-version="1.0.0", + com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/build.properties b/cave/com.raytheon.uf.viz.collaboration.radar/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/plugin.xml b/cave/com.raytheon.uf.viz.collaboration.radar/plugin.xml new file mode 100644 index 0000000000..587f2f6fc7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/plugin.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/Activator.java b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/Activator.java new file mode 100644 index 0000000000..88ee972452 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/Activator.java @@ -0,0 +1,30 @@ +package com.raytheon.uf.viz.collaboration.radar; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/mesh/CreateRadarRadialMesh.java b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/mesh/CreateRadarRadialMesh.java new file mode 100644 index 0000000000..e9f9d5c348 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/mesh/CreateRadarRadialMesh.java @@ -0,0 +1,263 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.radar.mesh; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.dataplugin.radar.RadarRecord; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Event class used to specify the creation of a radar radial mesh + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateRadarRadialMesh extends AbstractDispatchingObjectEvent + implements ICreationEvent { + + @DynamicSerializeElement + private Integer numBins; + + @DynamicSerializeElement + private Integer numRadials; + + @DynamicSerializeElement + private float[] angleData; + + @DynamicSerializeElement + private Integer gateResolution; + + @DynamicSerializeElement + private Float trueElevationAngle; + + @DynamicSerializeElement + private Integer jstart; + + @DynamicSerializeElement + private String format; + + @DynamicSerializeElement + private Float latitude; + + @DynamicSerializeElement + private Float longitude; + + @DynamicSerializeElement + private GeneralGridGeometry targetGeometry; + + /** + * @return the radarRecord + */ + public RadarRecord getRadarRecord() { + RadarRecord radarRecord = new RadarRecord(); + radarRecord.setAngleData(angleData); + radarRecord.setFormat(format); + radarRecord.setGateResolution(gateResolution); + radarRecord.setJstart(jstart); + radarRecord.setLatitude(latitude); + radarRecord.setLongitude(longitude); + radarRecord.setNumBins(numBins); + radarRecord.setNumRadials(numRadials); + radarRecord.setTrueElevationAngle(trueElevationAngle); + return radarRecord; + } + + /** + * @param radarRecord + * the radarRecord to set + */ + public void setRadarRecord(RadarRecord radarRecord) { + this.angleData = radarRecord.getAngleData(); + this.format = radarRecord.getFormat(); + this.gateResolution = radarRecord.getGateResolution(); + this.jstart = radarRecord.getJstart(); + this.latitude = radarRecord.getLatitude(); + this.longitude = radarRecord.getLongitude(); + this.numBins = radarRecord.getNumBins(); + this.numRadials = radarRecord.getNumRadials(); + this.trueElevationAngle = radarRecord.getTrueElevationAngle(); + } + + /** + * @return the targetGeometry + */ + public GeneralGridGeometry getTargetGeometry() { + return targetGeometry; + } + + /** + * @param targetGeometry + * the targetGeometry to set + */ + public void setTargetGeometry(GeneralGridGeometry targetGeometry) { + this.targetGeometry = targetGeometry; + } + + /** + * @return the numBins + */ + public Integer getNumBins() { + return numBins; + } + + /** + * @param numBins + * the numBins to set + */ + public void setNumBins(Integer numBins) { + this.numBins = numBins; + } + + /** + * @return the numRadials + */ + public Integer getNumRadials() { + return numRadials; + } + + /** + * @param numRadials + * the numRadials to set + */ + public void setNumRadials(Integer numRadials) { + this.numRadials = numRadials; + } + + /** + * @return the angleData + */ + public float[] getAngleData() { + return angleData; + } + + /** + * @param angleData + * the angleData to set + */ + public void setAngleData(float[] angleData) { + this.angleData = angleData; + } + + /** + * @return the gateResolution + */ + public Integer getGateResolution() { + return gateResolution; + } + + /** + * @param gateResolution + * the gateResolution to set + */ + public void setGateResolution(Integer gateResolution) { + this.gateResolution = gateResolution; + } + + /** + * @return the trueElevationAngle + */ + public Float getTrueElevationAngle() { + return trueElevationAngle; + } + + /** + * @param trueElevationAngle + * the trueElevationAngle to set + */ + public void setTrueElevationAngle(Float trueElevationAngle) { + this.trueElevationAngle = trueElevationAngle; + } + + /** + * @return the jstart + */ + public Integer getJstart() { + return jstart; + } + + /** + * @param jstart + * the jstart to set + */ + public void setJstart(Integer jstart) { + this.jstart = jstart; + } + + /** + * @return the format + */ + public String getFormat() { + return format; + } + + /** + * @param format + * the format to set + */ + public void setFormat(String format) { + this.format = format; + } + + /** + * @return the latitude + */ + public Float getLatitude() { + return latitude; + } + + /** + * @param latitude + * the latitude to set + */ + public void setLatitude(Float latitude) { + this.latitude = latitude; + } + + /** + * @return the longitude + */ + public Float getLongitude() { + return longitude; + } + + /** + * @param longitude + * the longitude to set + */ + public void setLongitude(Float longitude) { + this.longitude = longitude; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/mesh/DispatchingRadarMeshExtension.java b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/mesh/DispatchingRadarMeshExtension.java new file mode 100644 index 0000000000..1d3769ef3e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/mesh/DispatchingRadarMeshExtension.java @@ -0,0 +1,89 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.radar.mesh; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.dataplugin.radar.RadarRecord; +import com.raytheon.uf.viz.core.IMesh; +import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.DispatchGraphicsTarget; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingMesh; +import com.raytheon.viz.radar.rsc.image.IRadialMeshExtension; + +/** + * Radar mesh extension implementation which creates dispatching mesh that + * forwards key events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 13, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DispatchingRadarMeshExtension extends + GraphicsExtension implements + IRadialMeshExtension { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.radar.rsc.image.IRadialMeshExtension#constructMesh(com + * .raytheon.uf.common.dataplugin.radar.RadarRecord, + * org.geotools.coverage.grid.GeneralGridGeometry) + */ + @Override + public IMesh constructMesh(RadarRecord radarData, + GeneralGridGeometry targetGeometry) throws VizException { + DispatchingMesh wrapping = new DispatchingMesh(target + .getWrappedObject().getExtension(IRadialMeshExtension.class) + .constructMesh(radarData, targetGeometry), + target.getDispatcher()); + CreateRadarRadialMesh create = RemoteGraphicsEventFactory.createEvent( + CreateRadarRadialMesh.class, wrapping); + create.setRadarRecord(radarData); + create.setTargetGeometry(targetGeometry); + target.dispatch(create); + return wrapping; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension# + * getCompatibilityValue(com.raytheon.uf.viz.core.IGraphicsTarget) + */ + @Override + public int getCompatibilityValue(DispatchGraphicsTarget target) { + return Compatibilty.TARGET_COMPATIBLE; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/rendering/RadarGraphicsExtRenderingHandler.java b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/rendering/RadarGraphicsExtRenderingHandler.java new file mode 100644 index 0000000000..bc22713134 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.radar/src/com/raytheon/uf/viz/collaboration/radar/rendering/RadarGraphicsExtRenderingHandler.java @@ -0,0 +1,66 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.radar.rendering; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.display.Activator; +import com.raytheon.uf.viz.collaboration.display.rsc.rendering.CollaborationRenderingHandler; +import com.raytheon.uf.viz.collaboration.radar.mesh.CreateRadarRadialMesh; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.viz.radar.rsc.image.IRadialMeshExtension; + +/** + * Rendering handler for radar graphics extension objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 17, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class RadarGraphicsExtRenderingHandler extends + CollaborationRenderingHandler { + + @Subscribe + public void createRadarMesh(CreateRadarRadialMesh event) { + int meshId = event.getObjectId(); + IGraphicsTarget target = getGraphicsTarget(); + try { + dataManager.putRenderableObject( + meshId, + target.getExtension(IRadialMeshExtension.class) + .constructMesh(event.getRadarRecord(), + event.getTargetGeometry())); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/.classpath b/cave/com.raytheon.uf.viz.collaboration.ui/.classpath new file mode 100644 index 0000000000..751c8f2e50 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/.project b/cave/com.raytheon.uf.viz.collaboration.ui/.project new file mode 100644 index 0000000000..c2a54e2b9d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.collaboration.ui + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.collaboration.ui/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..73d5ac30b1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Wed Feb 15 10:54:29 CST 2012 +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.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +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/cave/com.raytheon.uf.viz.collaboration.ui/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.collaboration.ui/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..609826bd32 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/META-INF/MANIFEST.MF @@ -0,0 +1,23 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Collaboration UI Plugin +Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.ui;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.collaboration.ui.Activator +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Export-Package: com.raytheon.uf.viz.collaboration.ui +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.collaboration.comm;bundle-version="1.0.0", + org.eclipse.swt;bundle-version="3.6.1", + org.eclipse.ecf;bundle-version="3.1.0", + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.common.comm;bundle-version="1.12.1174", + com.raytheon.uf.viz.collaboration.display;bundle-version="1.0.0", + org.eclipse.ecf.presence;bundle-version="2.0.0", + com.raytheon.viz.ui;bundle-version="1.12.1174", + com.raytheon.uf.viz.drawing;bundle-version="1.0.0", + com.raytheon.viz.core;bundle-version="1.12.1174" +Bundle-ActivationPolicy: lazy +Import-Package: com.raytheon.uf.viz.core.maps.display diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/build.properties b/cave/com.raytheon.uf.viz.collaboration.ui/build.properties new file mode 100644 index 0000000000..62a9516a7d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +bin.includes = META-INF/,\ + .,\ + icons/,\ + plugin.xml,\ + localization/ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_collaborate.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_collaborate.gif new file mode 100644 index 0000000000..0840bc6094 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_collaborate.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_correction.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_correction.gif new file mode 100644 index 0000000000..252d7ebcb8 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_correction.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_group.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_group.gif new file mode 100644 index 0000000000..7492f8ac10 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/add_group.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/available.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/available.gif new file mode 100644 index 0000000000..36caf01ee1 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/available.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/away.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/away.gif new file mode 100644 index 0000000000..915a018ba6 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/away.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/browser.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/browser.gif new file mode 100644 index 0000000000..4d4c6bb165 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/browser.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/chats.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/chats.gif new file mode 100644 index 0000000000..21a902fd1a Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/chats.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/collab_editor.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/collab_editor.gif new file mode 100644 index 0000000000..27d15cc3cc Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/collab_editor.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/collapseall.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/collapseall.gif new file mode 100644 index 0000000000..a2d80a9044 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/collapseall.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/contact_disabled.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/contact_disabled.gif new file mode 100644 index 0000000000..c684f405b5 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/contact_disabled.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/data_provider.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/data_provider.gif new file mode 100644 index 0000000000..2711f08369 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/data_provider.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/do_not_disturb.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/do_not_disturb.gif new file mode 100644 index 0000000000..bc9b65f7a4 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/do_not_disturb.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/feed.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/feed.gif new file mode 100644 index 0000000000..cdf4e8f36e Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/feed.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/find.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/find.gif new file mode 100644 index 0000000000..eba31f7545 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/find.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/font.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/font.gif new file mode 100644 index 0000000000..2c24792a5e Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/font.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/group.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/group.gif new file mode 100644 index 0000000000..f9635268ed Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/group.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/invite.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/invite.gif new file mode 100644 index 0000000000..b949ac948a Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/invite.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/link_to_editor.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/link_to_editor.gif new file mode 100644 index 0000000000..870934b693 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/link_to_editor.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/local_group.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/local_group.gif new file mode 100644 index 0000000000..3d241a47b6 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/local_group.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/lock.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/lock.gif new file mode 100644 index 0000000000..b5975cf566 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/lock.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/log.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/log.gif new file mode 100644 index 0000000000..bc1f18500b Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/log.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/login.png b/cave/com.raytheon.uf.viz.collaboration.ui/icons/login.png new file mode 100644 index 0000000000..eac31cc390 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/login.png differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/logout.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/logout.gif new file mode 100644 index 0000000000..dc47edf069 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/logout.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/messages.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/messages.gif new file mode 100644 index 0000000000..27d15cc3cc Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/messages.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/multiple_draw.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/multiple_draw.gif new file mode 100644 index 0000000000..471ef2a09b Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/multiple_draw.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/print.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/print.gif new file mode 100644 index 0000000000..04cb84bf4f Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/print.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/refresh.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/refresh.gif new file mode 100644 index 0000000000..3ca04d06ff Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/refresh.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/remove_editor.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/remove_editor.gif new file mode 100644 index 0000000000..28fc79fadc Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/remove_editor.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/remove_group.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/remove_group.gif new file mode 100644 index 0000000000..68f66f4a08 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/remove_group.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/session_group.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/session_group.gif new file mode 100644 index 0000000000..a60af4ec90 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/session_group.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/icons/warning.gif b/cave/com.raytheon.uf.viz.collaboration.ui/icons/warning.gif new file mode 100644 index 0000000000..8e054d0731 Binary files /dev/null and b/cave/com.raytheon.uf.viz.collaboration.ui/icons/warning.gif differ diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/localization/collaboration/config.xml b/cave/com.raytheon.uf.viz.collaboration.ui/localization/collaboration/config.xml new file mode 100644 index 0000000000..ee9cc3e68a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/localization/collaboration/config.xml @@ -0,0 +1,49 @@ + + + + + + + + OAX + DMX + FSD + LBF + GID + TOP + EAX + NCEP + Short Term Forecaster + Long Term Forecaster + None + + + DMX + DVN + OAX + FSD + EAX + ARX + MPX + NCEP + Long Term Forecaster + Short Term Forecaster + None + + + GID + OAX + TOP + ICT + DDC + GLD + LBF + NCEP + Short Term Forecaster + Long Term Forecaster + None + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/plugin.xml b/cave/com.raytheon.uf.viz.collaboration.ui/plugin.xml new file mode 100644 index 0000000000..fdaf6dff0a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/plugin.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/AbstractUserLabelProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/AbstractUserLabelProvider.java new file mode 100644 index 0000000000..dd5bbab807 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/AbstractUserLabelProvider.java @@ -0,0 +1,167 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; + +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; + +/** + * Common code that is used whenever providing labels for users in a tree. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 24, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public abstract class AbstractUserLabelProvider extends ColumnLabelProvider { + + protected Map imageMap = new HashMap(); + + @Override + public String getText(Object element) { + if (!(element instanceof IUser)) { + return null; + } + IUser user = (IUser) element; + StringBuilder name = new StringBuilder(); + name.append(getDisplayName(user)); + IPresence presence = getPresence(user); + if (presence != null) { + Object site = presence.getProperties().get( + SiteConfigInformation.SITE_NAME); + if (site != null) { + name.append(" - "); + name.append(site); + } + Object role = presence.getProperties().get( + SiteConfigInformation.ROLE_NAME); + if (role != null) { + name.append(" - "); + name.append(role); + } + } + return name.toString(); + } + + @Override + public Image getImage(Object element) { + if (!(element instanceof IUser)) { + return null; + } + IUser user = (IUser) element; + IPresence presence = getPresence(user); + String key = ""; + if (presence != null && presence.getType() == Type.AVAILABLE) { + key = presence.getMode().toString().replaceAll("\\s+", "_"); + } else { + key = "contact_disabled"; + } + if (imageMap.get(key) == null && !key.equals("")) { + imageMap.put(key, CollaborationUtils.getNodeImage(key)); + } + return imageMap.get(key); + } + + @Override + public String getToolTipText(Object element) { + if (!(element instanceof IUser)) { + return null; + } + IUser user = (IUser) element; + IPresence presence = getPresence(user); + StringBuilder text = new StringBuilder(); + text.append("Name: ").append(getDisplayName(user)).append("\n"); + text.append("Status: "); + if (presence == null || presence.getType() != Type.AVAILABLE) { + text.append("Offline\n"); + } else { + text.append(CollaborationUtils.formatMode(presence.getMode())) + .append("\n"); + if (presence.getStatus() != null && !presence.getStatus().isEmpty()) { + text.append("Message : \"").append(presence.getStatus()) + .append("\"\n"); + } + for (Object key : presence.getProperties().keySet()) { + Object value = presence.getProperties().get(key); + if (value != null && key != null) { + text.append(key).append(" : ").append(value).append("\n"); + } + } + } + // delete trailing newline + text.deleteCharAt(text.length() - 1); + return text.toString(); + } + + @Override + public int getToolTipStyle(Object object) { + return SWT.SHADOW_OUT; + } + + @Override + public Point getToolTipShift(Object object) { + return new Point(5, 5); + } + + @Override + public void dispose() { + for (String key : imageMap.keySet()) { + imageMap.get(key).dispose(); + } + imageMap.clear(); + } + + protected String getDisplayName(IUser user) { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + String name = user.getNickname(); + if (name == null) { + name = user.getName(); + } + return name; + } else { + return connection.getContactsManager().getDisplayName(user); + } + } + + protected abstract IPresence getPresence(IUser user); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/Activator.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/Activator.java new file mode 100644 index 0000000000..d7dfcaae4e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/Activator.java @@ -0,0 +1,112 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import org.eclipse.core.runtime.preferences.InstanceScope; +import org.eclipse.jface.preference.IPersistentPreferenceStore; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.eclipse.ui.preferences.ScopedPreferenceStore; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; + +/** + * The activator class controls the plug-in life cycle + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class Activator extends AbstractUIPlugin { + + public static final IUFStatusHandler statusHandler = UFStatus + .getHandler(Activator.class); + + // The plug-in ID + public static final String PLUGIN_ID = "com.raytheon.uf.viz.collaboration.ui"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + private ScopedPreferenceStore prefs; + + /** + * 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; + if (this.prefs != null) { + this.prefs.save(); + } + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + @Override + public IPersistentPreferenceStore getPreferenceStore() { + if (prefs == null) { + prefs = new ScopedPreferenceStore(new InstanceScope(), PLUGIN_ID); + } + + return prefs; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ChangePasswordDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ChangePasswordDialog.java new file mode 100644 index 0000000000..0e3ffcb74d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ChangePasswordDialog.java @@ -0,0 +1,226 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 3, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class ChangePasswordDialog extends CaveSWTDialog { + + private Label userLabel; + + private Text passwordTF; + + private Text verifyPasswordTF; + + public ChangePasswordDialog(Shell parentShell) { + super(parentShell); + setText("Change Password"); + } + + private Control createDialogArea(Composite parent) { + UserId user = CollaborationConnection.getConnection().getUser(); + Composite body = new Composite(parent, SWT.NONE); + body.setLayout(new GridLayout(2, false)); + // body.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL + // | GridData.HORIZONTAL_ALIGN_FILL)); + Label label = null; + GridData gd = null; + userLabel = new Label(body, SWT.NONE); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + userLabel.setLayoutData(gd); + userLabel.setText(user.getName() + "@" + user.getHost()); + + label = new Label(body, SWT.NONE); + label.setText("New Password: "); + passwordTF = new Text(body, SWT.BORDER | SWT.PASSWORD); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + passwordTF.setLayoutData(gd); + + label = new Label(body, SWT.NONE); + label.setText("Verify Password: "); + verifyPasswordTF = new Text(body, SWT.BORDER | SWT.PASSWORD); + verifyPasswordTF.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + true)); + + return body; + } + + @Override + protected void initializeComponents(Shell shell) { + shell.setLayout(new GridLayout(1, false)); + createDialogArea(shell); + createButtonBar(shell); + } + + private void createButtonBar(Composite parent) { + GridData gd = null; + Composite bar = new Composite(parent, SWT.NONE); + + // set up to center buttons. + bar.setLayout(new GridLayout(0, true)); + gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); + bar.setLayoutData(gd); + createButton(bar, IDialogConstants.OK_ID, "Change", true); + + createButton(bar, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + @Override + protected void preOpened() { + super.preOpened(); + } + + /** + * Creates a new button with the given id. + *

+ * The Dialog implementation of this framework method creates a + * standard push button, registers it for selection events including button + * presses, and registers default buttons with its shell. The button id is + * stored as the button's client data. If the button id is + * IDialogConstants.CANCEL_ID, the new button will be + * accessible from getCancelButton(). If the button id is + * IDialogConstants.OK_ID, the new button will be accesible + * from getOKButton(). Note that the parent's layout is assumed + * to be a GridLayout and the number of columns in this layout + * is incremented. Subclasses may override. + *

+ * + * @param parent + * the parent composite + * @param id + * the id of the button (see IDialogConstants.*_ID + * constants for standard dialog button ids) + * @param label + * the label from the button + * @param defaultButton + * true if the button is to be the default button, + * and false otherwise + * + * @return the new button + * + * @see #getCancelButton + * @see #getOKButton() + */ + protected Button createButton(Composite parent, int id, String label, + boolean defaultButton) { + // increment the number of columns in the button bar + ((GridLayout) parent.getLayout()).numColumns++; + Button button = new Button(parent, SWT.PUSH); + button.setText(label); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumWidth = 70; + button.setLayoutData(gd); + button.setData(new Integer(id)); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + Integer val = (Integer) event.widget.getData(); + if (val != IDialogConstants.OK_ID) { + setReturnValue(null); + ChangePasswordDialog.this.getShell().dispose(); + } else { + Text focusField = null; + List errorMessages = new ArrayList(); + String password = passwordTF.getText(); + String verifyPassword = verifyPasswordTF.getText(); + if (password.length() == 0) { + errorMessages.add("Must enter new password."); + focusField = passwordTF; + verifyPasswordTF.setText(""); + } else if (verifyPassword.length() == 0) { + errorMessages.add("Enter password again to verify."); + focusField = verifyPasswordTF; + } else if (password.equals(verifyPassword) == false) { + errorMessages + .add("New and verified password do not match."); + errorMessages.add("Enter them again."); + focusField = passwordTF; + verifyPasswordTF.setText(""); + } + + if (focusField == null) { + setReturnValue(password); + ChangePasswordDialog.this.getShell().dispose(); + } else { + StringBuilder sb = new StringBuilder(); + String prefix = ""; + for (String msg : errorMessages) { + sb.append(prefix).append(msg); + prefix = "\n"; + } + MessageBox messageBox = new MessageBox(event.widget + .getDisplay().getActiveShell(), SWT.ERROR); + messageBox.setText("Change Password Error"); + messageBox.setMessage(sb.toString()); + messageBox.open(); + event.doit = false; + setReturnValue(null); + focusField.setFocus(); + focusField.selectAll(); + } + } + } + }); + if (defaultButton) { + Shell shell = parent.getShell(); + if (shell != null) { + shell.setDefaultButton(button); + } + } + return button; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java new file mode 100644 index 0000000000..2d1e573ac1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationGroupView.java @@ -0,0 +1,856 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.jface.window.ToolTip; +import org.eclipse.swt.SWT; +import org.eclipse.swt.accessibility.ACC; +import org.eclipse.swt.accessibility.AccessibleAdapter; +import org.eclipse.swt.accessibility.AccessibleControlAdapter; +import org.eclipse.swt.accessibility.AccessibleControlEvent; +import org.eclipse.swt.accessibility.AccessibleEvent; +import org.eclipse.swt.custom.TreeEditor; +import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.DisposeListener; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseMoveListener; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +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.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.internal.WorkbenchMessages; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.Bundle; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.event.UserPresenceChangedEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager.LocalGroupListener; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.actions.AddToGroupAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ArchiveViewerAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ChangeFontAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ChangePasswordAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ChangeRoleAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ChangeSiteAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ChangeStatusAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ChangeStatusMessageAction; +import com.raytheon.uf.viz.collaboration.ui.actions.CreateGroupAction; +import com.raytheon.uf.viz.collaboration.ui.actions.CreateSessionAction; +import com.raytheon.uf.viz.collaboration.ui.actions.DeleteGroupAction; +import com.raytheon.uf.viz.collaboration.ui.actions.DisplayFeedAction; +import com.raytheon.uf.viz.collaboration.ui.actions.InviteAction; +import com.raytheon.uf.viz.collaboration.ui.actions.LinkToEditorAction; +import com.raytheon.uf.viz.collaboration.ui.actions.LoginAction; +import com.raytheon.uf.viz.collaboration.ui.actions.LogoutAction; +import com.raytheon.uf.viz.collaboration.ui.actions.PeerToPeerChatAction; +import com.raytheon.uf.viz.collaboration.ui.actions.RemoveFromGroupAction; +import com.raytheon.uf.viz.collaboration.ui.actions.ShowVenueAction; +import com.raytheon.uf.viz.collaboration.ui.actions.UserSearchAction; +import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper; +import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer; +import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer; +import com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveFloatingView; + +/** + * This class is the main view to display the user's information and allow the + * user to create sessions. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012             rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class CollaborationGroupView extends CaveFloatingView implements + LocalGroupListener, IUserSelector { + public static final String ID = "com.raytheon.uf.viz.collaboration.ui.CollaborationGroupView"; + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CollaborationGroupView.class); + + private TreeViewer usersTreeViewer; + + // private List groups; + + private UsersTreeFilter usersTreeFilter; + + private CollaborationGroupContainer topLevel; + + private CreateSessionAction createSessionAction; + + private Action aliasAction; + + private DisplayFeedAction displayFeedAction; + + // private Action pgenAction; + + private Action collapseAllAction; + + private TreeEditor treeEditor; + + private Composite parent; + + /** + * @param parent + */ + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + this.parent = parent; + this.parent.setLayout(new GridLayout()); + // build the necessary actions for the view + createActions(); + + // add some actions to the toolbar + createToolbar(); + + // add some actions to the menubar + createMenubar(); + openConnection(); + } + + private void openConnection() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + new LoginAction().run(); + connection = CollaborationConnection.getConnection(); + if (connection == null) { + // user cancelled login + return; + } + } + + createFilterText(parent); + createUsersTree(parent); + addDoubleClickListeners(); + createContextMenu(); + + if (connection != null) { + connection.registerEventHandler(this); + } + connection.getContactsManager().addLocalGroupListener(this); + populateTree(); + usersTreeViewer.refresh(); + parent.layout(); + } + + @Override + public void dispose() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection != null) { + connection.unregisterEventHandler(this); + connection.getContactsManager().removeLocalGroupListener(this); + } + super.dispose(); + } + + /** + * + */ + private void createActions() { + Bundle bundle = Activator.getDefault().getBundle(); + final IUserSelector userSelector = this; + + createSessionAction = new CreateSessionAction(userSelector); + + aliasAction = new Action("Alias") { + @Override + public void run() { + aliasItem(getId()); + }; + }; + + collapseAllAction = new Action("Collapse All") { + public void run() { + if (usersTreeViewer != null) { + usersTreeViewer.collapseAll(); + } + } + }; + collapseAllAction.setImageDescriptor(IconUtil.getImageDescriptor( + bundle, "collapseall.gif")); + + // this is either on or off, so it is a toggle + displayFeedAction = new DisplayFeedAction(); + + this.disableOrEnableToolbarActions(); + } + + /** + * Create the toolbar on top of the group view + */ + private void createToolbar() { + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(createSessionAction); + mgr.add(displayFeedAction); + mgr.add(collapseAllAction); + mgr.add(LinkToEditorAction.getInstance(getViewSite() + .getWorkbenchWindow())); + } + + /** + * Create the menu bar that is shown when the user clicks the down arrow + * next to the toolbar + */ + private void createMenubar() { + IMenuManager mgr = getViewSite().getActionBars().getMenuManager(); + createMenu(mgr); + mgr.addMenuListener(new IMenuListener() { + + @Override + public void menuAboutToShow(IMenuManager manager) { + manager.removeAll(); + createMenu(manager); + } + }); + } + + private void createMenu(IMenuManager mgr) { + mgr.add(new CreateGroupAction()); + mgr.add(new UserSearchAction()); + mgr.add(new Separator()); + mgr.add(new ChangeFontAction()); + mgr.add(new ChangeStatusAction()); + mgr.add(new ChangeStatusMessageAction()); + mgr.add(new ChangePasswordAction()); + mgr.add(new Separator()); + mgr.add(new ChangeRoleAction()); + mgr.add(new ChangeSiteAction()); + mgr.add(new Separator()); + mgr.add(new ArchiveViewerAction()); + mgr.add(new Separator()); + + if (CollaborationConnection.getConnection() != null) { + mgr.add(new LogoutAction()); + } else { + mgr.add(new LoginAction()); + } + } + + private void createContextMenu() { + MenuManager menuMgr = new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + + @Override + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuMgr.createContextMenu(usersTreeViewer.getControl()); + usersTreeViewer.getControl().setMenu(menu); + getSite().registerContextMenu(menuMgr, usersTreeViewer); + } + + /** + * Get entries for all part of the Tree Viewer and enable actions. + */ + protected void populateTree() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + // set all the menu actions to false to start with + if (connection == null) { + usersTreeViewer.getTree().setEnabled(false); + return; + } + + // add ability to drop new groups as well as drop roster entries into + // new "custom" groups + addDragAndDrop(); + + // enable the tree, and then refresh it just to be safe + usersTreeViewer.getTree().setEnabled(true); + usersTreeViewer.refresh(topLevel, true); + this.disableOrEnableToolbarActions(); + } + + /** + * Filling the context menu for the tree depending on whether the item is a + * group or a user + * + * @paramfillContextMenu manager + */ + private void fillContextMenu(IMenuManager manager) { + TreeSelection selection = (TreeSelection) usersTreeViewer + .getSelection(); + Object o = selection.getFirstElement(); + + // handle the session group portion of the group view + if (o instanceof SessionGroupContainer) { + manager.add(createSessionAction); + return; + } else if (o instanceof IVenueSession) { + manager.add(new ShowVenueAction((IVenueSession) o)); + manager.add(new ArchiveViewerAction((IVenueSession) o)); + return; + } else if (o instanceof UserId) { + createMenu(manager); + return; + } + + // the user, both the logged in user as well as his buddies + if (o instanceof IUser) { + IUser user = (IUser) o; + IPresence presence = CollaborationConnection.getConnection() + .getContactsManager().getPresence(user); + if (presence != null && presence.getType() == Type.AVAILABLE) { + Action inviteAction = new InviteAction(user); + if (inviteAction.isEnabled()) { + manager.add(inviteAction); + } + Action p2pAction = new PeerToPeerChatAction(user); + if (p2pAction.isEnabled()) { + manager.add(p2pAction); + } + manager.add(new Separator()); + manager.add(createSessionAction); + } + String name = CollaborationConnection.getConnection() + .getContactsManager().getDisplayName(user); + aliasAction.setId(name); + aliasAction.setText("Alias"); + manager.add(aliasAction); + manager.add(new ArchiveViewerAction(user)); + manager.add(new AddToGroupAction(getSelectedUsers())); + String groupName = null; + Object group = selection.getPaths()[0].getFirstSegment(); + if (group instanceof LocalGroup) { + groupName = ((LocalGroup) group).getName(); + manager.add(new RemoveFromGroupAction(groupName, + getSelectedUsers())); + } + } else if (o instanceof IRosterGroup || o instanceof LocalGroup) { + manager.add(createSessionAction); + if (o instanceof LocalGroup) { + LocalGroup group = (LocalGroup) o; + manager.add(new DeleteGroupAction(group.getName())); + aliasAction.setId(group.getName()); + aliasAction.setText("Rename Group"); + manager.add(aliasAction); + } + } + } + + private void addDoubleClickListeners() { + usersTreeViewer.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + TreeSelection selection = (TreeSelection) usersTreeViewer + .getSelection(); + Object o = selection.getFirstElement(); + if (o instanceof IUser) { + new PeerToPeerChatAction((IUser) o).run(); + } else if (o instanceof IVenueSession) { + new ShowVenueAction((IVenueSession) o).run(); + } + } + }); + } + + /** + * Add the ability to alias items in the group view and then to have that + * alias be used anywhere else that the UserId is used + * + * Saves to an xml file in localization where the user can edit if desired + */ + protected void aliasItem(final String editableText) { + Control oldEditor = treeEditor.getEditor(); + if (oldEditor != null) { + oldEditor.dispose(); + } + TreeSelection selection = (TreeSelection) usersTreeViewer + .getSelection(); + final Object selectedObj = selection.getFirstElement(); + + final TreeItem item = usersTreeViewer.getTree().getSelection()[0]; + final Composite composite = new Composite(usersTreeViewer.getTree(), + SWT.NONE); + composite.setBackground(Display.getCurrent().getSystemColor( + SWT.COLOR_BLACK)); + final Text modText = new Text(composite, SWT.NONE); + composite.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event e) { + Rectangle rect = composite.getClientArea(); + modText.setBounds(rect.x + 1, rect.y + 1, rect.width - 2, + rect.height - 2); + } + }); + Listener textListener = new Listener() { + public void handleEvent(final Event e) { + switch (e.type) { + case SWT.KeyUp: + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + // do nothing, want to go on to the focus out + } else { + break; + } + case SWT.FocusOut: + String fullText = modText.getText(); + composite.dispose(); + changeText(selectedObj, fullText); + refreshUsersTreeViewerAsync(selectedObj); + break; + case SWT.Verify: + String newText = modText.getText(); + String leftText = newText.substring(0, e.start); + String rightText = newText.substring(e.end, + newText.length()); + GC gc = new GC(modText); + Point size = gc.textExtent(leftText + e.text + rightText); + gc.dispose(); + size = modText.computeSize(size.x, SWT.DEFAULT); + treeEditor.horizontalAlignment = SWT.LEFT; + Rectangle itemRect = item.getBounds(), + rect = usersTreeViewer.getTree().getClientArea(); + treeEditor.minimumWidth = Math.max(size.x, itemRect.width) + 2; + int left = itemRect.x, + right = rect.x + rect.width; + treeEditor.minimumWidth = Math.min(treeEditor.minimumWidth, + right - left); + treeEditor.minimumHeight = size.y + 2; + treeEditor.layout(); + break; + } + } + }; + + modText.addListener(SWT.KeyUp, textListener); + modText.addListener(SWT.Verify, textListener); + modText.addListener(SWT.FocusOut, textListener); + treeEditor.setEditor(composite, item); + + modText.setText(editableText); + modText.selectAll(); + modText.setFocus(); + } + + protected void changeText(Object selectedObj, String newText) { + if (selectedObj instanceof IUser) { + IUser user = (IUser) selectedObj; + UserId id = IDConverter.convertFrom(user); + id.setAlias(treeEditor.getItem().getText()); + CollaborationConnection.getConnection().getContactsManager() + .setNickname(user, newText); + CollaborationConnection.getConnection().postEvent(user); + for (LocalGroup group : CollaborationConnection.getConnection() + .getContactsManager().getLocalGroups(user)) { + usersTreeViewer.refresh(group); + } + } else if (selectedObj instanceof LocalGroup) { + LocalGroup group = (LocalGroup) selectedObj; + CollaborationConnection.getConnection().getContactsManager() + .renameLocalGroup(group.getName(), newText); + } + } + + /** + * Code was copied from FilteredTree, as FilteredTree did not offer an + * advanced enough matching capability + * + * This creates a nice looking text widget with a button embedded in the + * widget + * + * @param parent + */ + private void createFilterText(Composite parent) { + Composite comp = new Composite(parent, SWT.BORDER); + comp.setBackground(Display.getCurrent().getSystemColor( + SWT.COLOR_LIST_BACKGROUND)); + GridLayout layout = new GridLayout(2, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + comp.setLayout(layout); + GridData gd = new GridData(SWT.FILL, SWT.NONE, true, false); + comp.setLayoutData(gd); + + final Text text = new Text(comp, SWT.SINGLE | SWT.NONE); + GridData data = new GridData(SWT.FILL, SWT.NONE, true, false); + text.setLayoutData(data); + text.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + filter(text); + } + }); + + // only create the button if the text widget doesn't support one + // natively + final Image inactiveImage = AbstractUIPlugin.imageDescriptorFromPlugin( + PlatformUI.PLUGIN_ID, "$nl$/icons/full/dtool16/clear_co.gif") + .createImage(); + final Image activeImage = AbstractUIPlugin.imageDescriptorFromPlugin( + PlatformUI.PLUGIN_ID, "$nl$/icons/full/etool16/clear_co.gif") + .createImage(); + final Image pressedImage = new Image(Display.getCurrent(), activeImage, + SWT.IMAGE_GRAY); + final Label clearButton = new Label(comp, SWT.NONE); + clearButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, + false, false)); + clearButton.setImage(inactiveImage); + clearButton.setBackground(parent.getDisplay().getSystemColor( + SWT.COLOR_LIST_BACKGROUND)); + clearButton.setToolTipText(WorkbenchMessages.FilteredTree_ClearToolTip); + clearButton.addMouseListener(new MouseAdapter() { + private MouseMoveListener fMoveListener; + + public void mouseDown(MouseEvent e) { + clearButton.setImage(pressedImage); + fMoveListener = new MouseMoveListener() { + private boolean fMouseInButton = true; + + public void mouseMove(MouseEvent e) { + boolean mouseInButton = isMouseInButton(e); + if (mouseInButton != fMouseInButton) { + fMouseInButton = mouseInButton; + clearButton.setImage(mouseInButton ? pressedImage + : inactiveImage); + } + } + }; + clearButton.addMouseMoveListener(fMoveListener); + } + + public void mouseUp(MouseEvent e) { + if (fMoveListener != null) { + clearButton.removeMouseMoveListener(fMoveListener); + fMoveListener = null; + boolean mouseInButton = isMouseInButton(e); + clearButton.setImage(mouseInButton ? activeImage + : inactiveImage); + if (mouseInButton) { + text.setText(""); + filter(text); + text.setFocus(); + } + } + } + + private boolean isMouseInButton(MouseEvent e) { + Point buttonSize = clearButton.getSize(); + return 0 <= e.x && e.x < buttonSize.x && 0 <= e.y + && e.y < buttonSize.y; + } + }); + clearButton.addMouseTrackListener(new MouseTrackAdapter() { + public void mouseEnter(MouseEvent e) { + clearButton.setImage(activeImage); + } + + public void mouseExit(MouseEvent e) { + clearButton.setImage(inactiveImage); + } + }); + clearButton.addDisposeListener(new DisposeListener() { + public void widgetDisposed(DisposeEvent e) { + inactiveImage.dispose(); + activeImage.dispose(); + pressedImage.dispose(); + } + }); + clearButton.getAccessible().addAccessibleListener( + new AccessibleAdapter() { + public void getName(AccessibleEvent e) { + e.result = WorkbenchMessages.FilteredTree_AccessibleListenerClearButton; + } + }); + clearButton.getAccessible().addAccessibleControlListener( + new AccessibleControlAdapter() { + public void getRole(AccessibleControlEvent e) { + e.detail = ACC.ROLE_PUSHBUTTON; + } + }); + } + + /** + * Function to run through the tree and expand all elements if something is + * typed in the filter field, otherwise collapse them all + * + * @param text + */ + private void filter(Text text) { + // call refresh on the tree to get the most up-to-date children + usersTreeViewer.refresh(false); + + if (usersTreeFilter == null) { + ViewerFilter[] filters = new ViewerFilter[1]; + usersTreeFilter = new UsersTreeFilter(); + filters[0] = usersTreeFilter; + usersTreeViewer.setFilters(filters); + } + + // set the current filter text so that it can be used when refresh is + // called again + usersTreeFilter.setCurrentText(text.getText()); + if (text.getText().length() == 0) { + for (Object ob : topLevel.getObjects()) { + usersTreeViewer.setExpandedState(ob, false); + } + } + // if text contains anything then expand all items in the tree + if (text.getText().length() > 0) { + for (Object ob : topLevel.getObjects()) { + usersTreeViewer.setExpandedState(ob, true); + } + } + // call refresh on the tree after things are expanded + usersTreeViewer.refresh(false); + } + + /** + * Generate the Tree View component and add tooltip tracking. + * + * @param parent + */ + private void createUsersTree(Composite parent) { + Composite child = new Composite(parent, SWT.NONE); + child.setLayout(new GridLayout(1, false)); + child.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + usersTreeViewer = new TreeViewer(child, SWT.VIRTUAL | SWT.MULTI + | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); + usersTreeViewer.getTree().setLayoutData( + new GridData(SWT.FILL, SWT.FILL, true, true)); + + TreeColumn column = new TreeColumn(usersTreeViewer.getTree(), SWT.NONE); + column.setWidth(200); // any width would work + + usersTreeViewer.setContentProvider(new UsersTreeContentProvider()); + usersTreeViewer.setLabelProvider(new UsersTreeLabelProvider()); + usersTreeViewer.setSorter(new UsersTreeViewerSorter()); + ColumnViewerToolTipSupport.enableFor(usersTreeViewer, ToolTip.RECREATE); + topLevel = new CollaborationGroupContainer(); + usersTreeViewer.setInput(topLevel); + + treeEditor = new TreeEditor(usersTreeViewer.getTree()); + } + + /** + * Get a unique set of selected users that have a Type of AVAILABLE. This + * does a recursive search so will work even when groups contain groups. + * + * @return + */ + public IUser[] getSelectedUsers() { + Set selectedUsers = new HashSet(); + IStructuredSelection selection = (IStructuredSelection) usersTreeViewer + .getSelection(); + Object[] nodes = selection.toArray(); + + for (Object node : nodes) { + if (node instanceof IUser) { + IUser user = (IUser) node; + selectedUsers.add(user); + } else if (node instanceof IRosterGroup) { + selectedUsers.addAll(getSelectedUsers((IRosterGroup) node)); + } else if (node instanceof LocalGroup) { + for (IUser user : ((LocalGroup) node).getUsers()) { + IPresence presence = CollaborationConnection + .getConnection().getContactsManager() + .getPresence(user); + if (presence.getType() == IPresence.Type.AVAILABLE) { + selectedUsers.add(user); + } + } + } + } + + return selectedUsers.toArray(new IUser[selectedUsers.size()]); + } + + /** + * This recursively searches group Nodes and returns all users with Type + * AVAILABLE. + * + * @param groupNode + * @return users + */ + private Set getSelectedUsers(IRosterGroup groupNode) { + Set selectedUsers = new HashSet(); + for (Object node : groupNode.getEntries()) { + if (node instanceof IRosterEntry) { + IRosterEntry user = (IRosterEntry) node; + if (user.getPresence().getType() == Type.AVAILABLE) { + selectedUsers.add(((IRosterEntry) node).getUser()); + } + } else if (node instanceof IRosterGroup) { + selectedUsers.addAll(getSelectedUsers((IRosterGroup) node)); + } + } + return selectedUsers; + } + + private void refreshUsersTreeViewerAsync(final Object element) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + usersTreeViewer.refresh(element); + } + }); + } + + /** + * Refresh the labels on the View Tree to reflect presence change. + * + * @param rosterEntry + */ + @Subscribe + public void handleModifiedPresence(UserPresenceChangedEvent event) { + refreshUsersTreeViewerAsync(CollaborationConnection.getConnection() + .getUser()); + } + + @Subscribe + public void addAlertWords(AlertWordWrapper words) { + for (IViewReference ref : getViewSite().getWorkbenchWindow() + .getActivePage().getViewReferences()) { + IViewPart viewPart = ref.getView(false); + if (viewPart instanceof AbstractSessionView) { + ((AbstractSessionView) viewPart).setAlertWords(Arrays + .asList(words.getAlertWords())); + } + } + } + + @Subscribe + public void handleRosterChangeEvent(IRosterChangeEvent rosterChangeEvent) { + // Refresh the whole tree since there can be instances of the same user + // elsewhere that might not .equals this one. + refreshUsersTreeViewerAsync(usersTreeViewer.getInput()); + } + + @Subscribe + public void handlSessionEvent(IVenueSession rosterChangeEvent) { + refreshUsersTreeViewerAsync(topLevel.getSessionGroup()); + } + + /** + * Enables or disables the toolbar buttons based on whether or not the user + * is connected to the xmpp server. + */ + private void disableOrEnableToolbarActions() { + boolean enabled = (CollaborationConnection.getConnection() != null); + createSessionAction.setEnabled(enabled); + displayFeedAction.setEnabled(enabled); + collapseAllAction.setEnabled(enabled); + LinkToEditorAction.getInstance(getViewSite().getWorkbenchWindow()); + } + + private void addDragAndDrop() { + // CollaborationGroupDragNDrop dragNDropSource = new + // CollaborationGroupDragNDrop( + // usersTreeViewer); + // usersTreeViewer.addDragSupport(DND.DROP_MOVE | DND.DROP_COPY, + // new Transfer[] { TextTransfer.getInstance() }, dragNDropSource); + // usersTreeViewer.addDropSupport(DND.DROP_MOVE | DND.DROP_COPY, + // new Transfer[] { TextTransfer.getInstance() }, dragNDropSource); + } + + // Does nothing, but necessary due to ViewPart + @Override + public void setFocus() { + // nothing to do in this method + } + + @Override + public void groupCreated(LocalGroup group) { + refreshUsersTreeViewerAsync(usersTreeViewer.getInput()); + } + + @Override + public void groupDeleted(LocalGroup group) { + refreshUsersTreeViewerAsync(usersTreeViewer.getInput()); + } + + @Override + public void userAdded(LocalGroup group, IUser user) { + refreshUsersTreeViewerAsync(group); + } + + @Override + public void userDeleted(LocalGroup group, IUser user) { + refreshUsersTreeViewerAsync(group); + } + + @Subscribe + public void userNicknameChanged(UserNicknameChangedEvent e) { + refreshUsersTreeViewerAsync(usersTreeViewer.getInput()); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationUtils.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationUtils.java new file mode 100644 index 0000000000..c1980a9db9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CollaborationUtils.java @@ -0,0 +1,181 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXB; + +import org.eclipse.ecf.presence.IPresence.Mode; +import org.eclipse.swt.graphics.Image; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserIdWrapper; +import com.raytheon.uf.viz.collaboration.ui.data.AlertWord; +import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Methods for sending, receiving messages + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationUtils { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CollaborationUtils.class); + + public static final org.eclipse.ecf.presence.IPresence.Mode[] statusModes = { + Mode.AVAILABLE, Mode.DND, Mode.AWAY }; + + private static final String PREFIX_CONFERENCE = "conference."; + + /** + * Get an image associated with the node. + * + * @param node + * @return image + */ + public static Image getNodeImage(String name) { + return IconUtil.getImageDescriptor(Activator.getDefault().getBundle(), + name.toLowerCase() + ".gif").createImage(); + } + + public static UserId[] getIds() { + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = PathManagerFactory.getPathManager() + .getLocalizationFile( + context, + "collaboration" + File.separator + + "collaborationAliases.xml"); + if (file.exists()) { + UserIdWrapper ids = (UserIdWrapper) JAXB.unmarshal(file.getFile(), + UserIdWrapper.class); + if (ids.getUserIds() == null) { + return new UserId[0]; + } + return ids.getUserIds(); + } + return new UserId[0]; + } + + public static String formatMode(Mode mode) { + String name = mode.toString(); + + StringBuilder result = new StringBuilder(name.length()); + String[] words = name.split("\\s"); + for (int i = 0, l = words.length; i < l; ++i) { + if (i > 0) + result.append(" "); + result.append(Character.toUpperCase(words[i].charAt(0))).append( + words[i].substring(1)); + + } + + return result.toString(); + } + + public static List getAlertWords() { + LocalizationFile file = null; + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + file = PathManagerFactory.getPathManager().getLocalizationFile(context, + "collaboration" + File.separator + "alertWords.xml"); + if (file.exists() || file.getFile().exists()) { + AlertWordWrapper words = (AlertWordWrapper) JAXB.unmarshal( + file.getFile(), AlertWordWrapper.class); + if (words.getAlertWords() == null) { + return new ArrayList(); + } else { + List alertWords = new ArrayList(); + for (int i = 0; i < words.getAlertWords().length; i++) { + alertWords.add(words.getAlertWords()[i]); + } + return alertWords; + } + } else { + return new ArrayList(); + } + } + + public static void saveAlertWords(List words) { + LocalizationFile file = null; + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext context = pm.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + file = PathManagerFactory.getPathManager().getLocalizationFile(context, + "collaboration" + File.separator + "alertWords.xml"); + + // save the sound file in the correct place if not there + for (AlertWord word : words) { + String soundPath = word.getSoundPath(); + if (soundPath != null && !soundPath.isEmpty()) { + String[] dirs = soundPath.split(File.separator); + String filename = dirs[dirs.length - 1]; + LocalizationFile lFile = pm.getLocalizationFile(context, + "collaboration" + File.separator + "sounds" + + File.separator + filename); + if (!lFile.exists()) { + File soundFile = new File(soundPath); + + File destination = lFile.getFile(); + soundFile.renameTo(destination); + } + } + } + + AlertWordWrapper wrapper = new AlertWordWrapper(); + wrapper.setAlertWords(words.toArray(new AlertWord[0])); + JAXB.marshal(wrapper, file.getFile()); + try { + file.save(); + } catch (LocalizationOpFailedException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to save alert words to localization", e); + } + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ConnectionSubscriber.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ConnectionSubscriber.java new file mode 100644 index 0000000000..1f85a878a6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/ConnectionSubscriber.java @@ -0,0 +1,285 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IHttpdCollaborationConfigurationEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.ITextMessageEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueInvitationEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.SharedDisplayVenueInvite; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.ui.actions.PeerToPeerChatAction; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; +import com.raytheon.uf.viz.collaboration.ui.session.CollaborationSessionView; +import com.raytheon.uf.viz.collaboration.ui.session.PeerToPeerView; +import com.raytheon.uf.viz.collaboration.ui.session.SessionView; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Subscribes to events that occur on the collaboration connection, ie the + * logged in user. This is for events not tied to a particular session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 8, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class ConnectionSubscriber { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ConnectionSubscriber.class); + + private static ConnectionSubscriber instance; + + private IWorkbenchListener wbListener; + + private ConnectionSubscriber() { + + } + + /** + * Subscribes to events on the given connection. Should only be called on + * login. + * + * @param connection + */ + public static void subscribe(CollaborationConnection connection) { + if (instance == null) { + instance = new ConnectionSubscriber(); + instance.setup(connection); + } + } + + /** + * Unsubscribes from events on the given connection. Should only be called + * on logout. + * + * @param connection + */ + public static void unsubscribe(CollaborationConnection connection) { + if (instance != null) { + instance.dispose(connection); + } + + instance = null; + } + + private void setup(final CollaborationConnection connection) { + if (connection != null) { + // Register handlers and events for the new sessionManager. + connection.registerEventHandler(this); + try { + ISession p2pSession = connection.getPeerToPeerSession(); + p2pSession.registerEventHandler(this); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error registering peer to peer handler", e); + } + // TODO the wblistener should perhaps be elsewhere + wbListener = new IWorkbenchListener() { + + @Override + public boolean preShutdown(IWorkbench workbench, boolean forced) { + return true; + } + + @Override + public void postShutdown(IWorkbench workbench) { + dispose(connection); + if (connection != null) { + connection.close(); + } + } + }; + PlatformUI.getWorkbench().addWorkbenchListener(wbListener); + } + + } + + private void dispose(CollaborationConnection connection) { + if (connection != null) { + try { + ISession p2pSession = connection.getPeerToPeerSession(); + p2pSession.unregisterEventHandler(this); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Error unregistering peer to peer handler", e); + } + connection.unregisterEventHandler(this); + } + PlatformUI.getWorkbench().removeWorkbenchListener(wbListener); + } + + @Subscribe + public void handleInvitationEvent(IVenueInvitationEvent event) { + final IVenueInvitationEvent invitation = event; + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + IQualifiedID inviter = invitation.getInviter(); + IQualifiedID room = invitation.getRoomId(); + Shell shell = new Shell(Display.getCurrent()); + StringBuilder sb = new StringBuilder(); + boolean sharedDisplay = invitation.getInvite() instanceof SharedDisplayVenueInvite; + sb.append("You are invited to a "); + if (sharedDisplay) { + sb.append("collaboration session."); + } else { + sb.append("chat room."); + } + InviteDialog inviteBox = new InviteDialog(shell, inviter + .getName(), invitation.getSubject(), room.getName(), sb + .toString(), invitation.getInvite().getMessage()); + if (!(Boolean) inviteBox.open()) { + return; + } + + CollaborationConnection connection = CollaborationConnection + .getConnection(); + try { + IVenueSession session = connection + .joinCollaborationVenue(invitation); + String sessionId = session.getSessionId(); + if (sharedDisplay) { + ISharedDisplaySession displaySession = (ISharedDisplaySession) session; + SessionColorManager man = new SessionColorManager(); + SharedDisplaySessionMgr.joinSession(displaySession, + SharedDisplayRole.PARTICIPANT, man); + + CaveWorkbenchPageManager.getActiveInstance().showView( + CollaborationSessionView.ID, sessionId, + IWorkbenchPage.VIEW_ACTIVATE); + } else { + CaveWorkbenchPageManager.getActiveInstance().showView( + SessionView.ID, sessionId, + IWorkbenchPage.VIEW_ACTIVATE); + } + } catch (CollaborationException e) { + // TODO Auto-generated catch block. Please revise as + // appropriate. + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } catch (PartInitException e) { + // TODO Auto-generated catch block. Please revise as + // appropriate. + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + }); + } + + /** + * This takes a peer to peer message and displays it in the proper view. + * + * @param messageEvent + */ + @Subscribe + public void peer2peerMessage(ITextMessageEvent messageEvent) { + final TextMessage message = messageEvent.getMessage(); + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + IQualifiedID peer = message.getFrom(); + + IUser user = null; + if (peer instanceof IUser) { + user = (IUser) peer; + } else { + user = CollaborationConnection.getConnection() + .getContactsManager().getUser(peer.getFQName()); + } + PeerToPeerView view = new PeerToPeerChatAction(user) + .createP2PChat(IWorkbenchPage.VIEW_CREATE); + message.setFrom(view.getPeer()); + if (view != null) { + view.appendMessage(message); + } + } + }); + } + + @Subscribe + public void handleHttpdConfigurationEvent( + IHttpdCollaborationConfigurationEvent configurationEvent) { + + boolean wasPreviouslyConfigured = Activator + .getDefault() + .getPreferenceStore() + .getBoolean( + CollabPrefConstants.HttpCollaborationConfiguration.P_SESSION_CONFIGURED); + boolean configured = false; + if ((configurationEvent.getHttpdCollaborationURL() == null) == false) { + // Add the httpd collaboration url to the CAVE configuration. + Activator + .getDefault() + .getPreferenceStore() + .setValue( + CollabPrefConstants.HttpCollaborationConfiguration.P_HTTP_SESSION_URL, + configurationEvent.getHttpdCollaborationURL()); + configured = true; + if (wasPreviouslyConfigured == false) { + statusHandler + .handle(Priority.INFO, + "Collaboration: Shared Display Sessions have been enabled."); + } + } + Activator + .getDefault() + .getPreferenceStore() + .setValue( + CollabPrefConstants.HttpCollaborationConfiguration.P_SESSION_CONFIGURED, + configured); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateGroupDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateGroupDialog.java new file mode 100644 index 0000000000..96ae44ba3d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateGroupDialog.java @@ -0,0 +1,126 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +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.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 27, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class CreateGroupDialog extends CaveSWTDialog { + + private Text nameText; + + private String newGroup = null; + + public CreateGroupDialog(Shell parentShell) { + super(parentShell, SWT.DIALOG_TRIM); + setText("Create Group"); + } + + @Override + protected void initializeComponents(Shell shell) { + Composite entryComp = new Composite(shell, SWT.NONE); + RowLayout layout = new RowLayout(SWT.HORIZONTAL); + layout.center = true; + entryComp.setLayout(layout); + new Label(entryComp, SWT.NONE).setText("Group Name: "); + nameText = new Text(entryComp, SWT.BORDER); + nameText.setLayoutData(new RowData(100, SWT.DEFAULT)); + nameText.addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + finish(); + } + } + + }); + Composite buttonComp = new Composite(shell, SWT.NONE); + buttonComp.setLayoutData(new GridData(SWT.RIGHT, SWT.NONE, false, + false, 1, 1)); + layout = new RowLayout(SWT.HORIZONTAL); + layout.pack = false; + buttonComp.setLayout(layout); + Button okButton = new Button(buttonComp, SWT.PUSH); + okButton.setText("OK"); + okButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + finish(); + } + + }); + + Button cancelButton = new Button(buttonComp, SWT.PUSH); + cancelButton.setText("Cancel"); + cancelButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + + }); + } + + private void finish() { + newGroup = nameText.getText(); + CollaborationConnection.getConnection().getContactsManager() + .createLocalGroup(newGroup); + close(); + } + + public String getNewGroup() { + return newGroup; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateSessionData.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateSessionData.java new file mode 100644 index 0000000000..621c05b274 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateSessionData.java @@ -0,0 +1,99 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 7, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class CreateSessionData { + private String name; + + private String subject; + + private boolean inviteUsers; + + private boolean collaborationSession; + + private String inviteMessage; + + private String sessionId; + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public boolean isCollaborationSession() { + return collaborationSession; + } + + public boolean isInviteUsers() { + return inviteUsers; + } + + public void setCollaborationSessioh(boolean collaborationSession) { + this.collaborationSession = collaborationSession; + } + + public void setInviteUsers(boolean inviteUsers) { + this.inviteUsers = inviteUsers; + } + + public String getInviteMessage() { + return inviteMessage; + } + + public void setInviteMessage(String inviteMessage) { + this.inviteMessage = inviteMessage; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateSessionDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateSessionDialog.java new file mode 100644 index 0000000000..bb6f66cb34 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/CreateSessionDialog.java @@ -0,0 +1,504 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.VerifyEvent; +import org.eclipse.swt.events.VerifyListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.ISharedEditorsManagerListener; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.collaboration.ui.editor.CollaborationEditor; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.maps.display.MapRenderableDisplay; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.raytheon.viz.ui.editor.IMultiPaneEditor; + +/** + * Collaboration creation dialog for sessions. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 15, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class CreateSessionDialog extends CaveSWTDialog { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CreateSessionDialog.class); + + private Text nameTF; + + private Text subjectTF; + + private Button sharedSessionDisplay; + + private Button inviteUsers; + + private StyledText inviteMessageTF; + + private Label inviteLabel; + + private IPartListener editorChangeListener; + + private ISharedEditorsManagerListener sharedEditorsListener; + + public CreateSessionDialog(Shell parentShell) { + super(parentShell); + setText("Create Session"); + } + + private Control createDialogArea(Composite parent) { + Composite body = new Composite(parent, SWT.NONE); + body.setLayout(new GridLayout(2, false)); + // body.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL + // | GridData.HORIZONTAL_ALIGN_FILL)); + Label label = null; + label = new Label(body, SWT.NONE); + label.setText("Name: "); + nameTF = new Text(body, SWT.BORDER); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumWidth = 200; + nameTF.setLayoutData(gd); + nameTF.addVerifyListener(new VerifyListener() { + + @Override + public void verifyText(VerifyEvent e) { + if (" \t\"&'/,<>@".indexOf(e.character) >= 0) { + e.doit = false; + // Toolkit.getDefaultToolkit().beep(); + } + } + }); + + label = new Label(body, SWT.NONE); + label.setText("Subject: "); + subjectTF = new Text(body, SWT.BORDER); + subjectTF.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + sharedSessionDisplay = new Button(body, SWT.CHECK); + gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + gd.horizontalSpan = 2; + sharedSessionDisplay.setLayoutData(gd); + updateSharedSessionDisplay(); + + inviteUsers = new Button(body, SWT.CHECK); + inviteUsers.setSelection(true); + gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + gd.horizontalSpan = 2; + inviteUsers.setLayoutData(gd); + inviteUsers.setText("Invite Selected Users"); + // inviteUsers.setSelection(true); + inviteUsers.setVisible(true); + // label = new Label(body, SWT.NONE); + // label.setText(""); + // label.setVisible(showInvite); + inviteLabel = new Label(body, SWT.NONE); + inviteLabel.setText("Message: "); + inviteLabel.setToolTipText("Message to send to invited users"); + inviteMessageTF = new StyledText(body, SWT.BORDER | SWT.MULTI + | SWT.WRAP | SWT.V_SCROLL); + inviteMessageTF.setLayoutData(new GridData(GridData.FILL_BOTH)); + inviteMessageTF.pack(); + inviteMessageTF.setToolTipText("Message to send to invited users"); + Point p = inviteMessageTF.getSize(); + gd = (GridData) inviteMessageTF.getLayoutData(); + gd.heightHint = p.y * 3; + inviteUsers.addSelectionListener(new SelectionListener() { + + @Override + public void widgetSelected(SelectionEvent e) { + boolean selected = ((Button) e.widget).getSelection(); + inviteLabel.setVisible(selected); + inviteMessageTF.setVisible(selected); + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + boolean selected = ((Button) e.widget).getSelection(); + inviteLabel.setVisible(selected); + inviteMessageTF.setVisible(selected); + + } + }); + inviteLabel.setVisible(true); + inviteMessageTF.setVisible(true); + + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + if (page != null) { + editorChangeListener = new IPartListener() { + + @Override + public void partOpened(IWorkbenchPart part) { + // not used + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + // not used + } + + @Override + public void partClosed(IWorkbenchPart part) { + // not used + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + // not used + } + + @Override + public void partActivated(IWorkbenchPart part) { + if (part instanceof IEditorPart) { + updateSharedSessionDisplay(); + } + } + }; + page.addPartListener(editorChangeListener); + } + + AbstractEditor editor = EditorUtil + .getActiveEditorAs(AbstractEditor.class); + if (editor != null) { + ISharedDisplaySession session = SharedEditorsManager + .getSharedEditorSession(editor); + if (session != null) { + sharedEditorsListener = new ISharedEditorsManagerListener() { + @Override + public void shareEditor(AbstractEditor editor) { + updateSharedSessionDisplay(); + } + + @Override + public void removeEditor(AbstractEditor editor) { + updateSharedSessionDisplay(); + } + }; + SharedEditorsManager.getManager(session).addListener( + sharedEditorsListener); + } + } + return body; + } + + private static boolean isShareable(IWorkbenchPart part) { + if (part instanceof AbstractEditor) { + AbstractEditor ed = (AbstractEditor) part; + IDisplayPane pane = ed.getActiveDisplayPane(); + IRenderableDisplay display = pane.getRenderableDisplay(); + IDisplayPaneContainer container = display.getContainer(); + boolean isMapDisplay = display instanceof MapRenderableDisplay; + boolean hasMultiplePanes = container instanceof IMultiPaneEditor + && ((IMultiPaneEditor) container).getNumberofPanes() > 1; + return (isMapDisplay && !hasMultiplePanes); + } + return false; + } + + private void updateSharedSessionDisplay() { + IEditorPart editor = EditorUtil.getActiveEditorAs(IEditorPart.class); + + if (!sharedSessionDisplay.isDisposed()) { + if (editor instanceof CollaborationEditor) { + sharedSessionDisplay + .setText("Create Shared Display Session *Client Session*"); + sharedSessionDisplay.setEnabled(false); + sharedSessionDisplay.setSelection(false); + sharedSessionDisplay.getParent().setToolTipText( + "Unable to create a shared display session because" + + " the active editor is a client session."); + } else if (!isShareable(editor)) { + sharedSessionDisplay + .setText("Create Shared Display Session *Not Shareable*"); + sharedSessionDisplay.setEnabled(false); + sharedSessionDisplay.setSelection(false); + sharedSessionDisplay.getParent().setToolTipText( + "Unable to create a shared display session because" + + " the active editor is not shareable."); + } else if (editor != null + && editor instanceof AbstractEditor + && SharedEditorsManager + .isBeingShared((AbstractEditor) editor)) { + sharedSessionDisplay + .setText("Create Shared Display Session *Already Shared*"); + sharedSessionDisplay.setEnabled(false); + sharedSessionDisplay.setSelection(false); + sharedSessionDisplay.getParent().setToolTipText( + "Unable to create a shared display session because" + + " the active editor is already " + + "in a shared display session."); + } else { + sharedSessionDisplay.setText("Create Shared Display Session"); + sharedSessionDisplay.getParent().setToolTipText(""); + this.enableOrDisableSharedDisplays(); + } + } + } + + @Override + protected void disposed() { + super.disposed(); + if (editorChangeListener != null) { + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + page.removePartListener(editorChangeListener); + } + if (sharedEditorsListener != null) { + AbstractEditor editor = EditorUtil + .getActiveEditorAs(AbstractEditor.class); + if (editor != null) { + ISharedDisplaySession session = SharedEditorsManager + .getSharedEditorSession(editor); + if (session != null) { + SharedEditorsManager.getManager(session).removeListener( + sharedEditorsListener); + } + } + } + } + + @Override + protected void initializeComponents(Shell shell) { + shell.setLayout(new GridLayout(1, false)); + createDialogArea(shell); + createButtonBar(shell); + } + + private void createButtonBar(Composite parent) { + GridData gd = null; + Composite bar = new Composite(parent, SWT.NONE); + + // set up to center buttons. + bar.setLayout(new GridLayout(0, true)); + gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); + bar.setLayoutData(gd); + createButton(bar, IDialogConstants.OK_ID, "Create", true); + + createButton(bar, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + @Override + protected void preOpened() { + super.preOpened(); + } + + /** + * Creates a new button with the given id. + *

+ * The Dialog implementation of this framework method creates a + * standard push button, registers it for selection events including button + * presses, and registers default buttons with its shell. The button id is + * stored as the button's client data. If the button id is + * IDialogConstants.CANCEL_ID, the new button will be + * accessible from getCancelButton(). If the button id is + * IDialogConstants.OK_ID, the new button will be accesible + * from getOKButton(). Note that the parent's layout is assumed + * to be a GridLayout and the number of columns in this layout + * is incremented. Subclasses may override. + *

+ * + * @param parent + * the parent composite + * @param id + * the id of the button (see IDialogConstants.*_ID + * constants for standard dialog button ids) + * @param label + * the label from the button + * @param defaultButton + * true if the button is to be the default button, + * and false otherwise + * + * @return the new button + * + * @see #getCancelButton + * @see #getOKButton() + */ + protected Button createButton(Composite parent, int id, String label, + boolean defaultButton) { + // increment the number of columns in the button bar + ((GridLayout) parent.getLayout()).numColumns++; + Button button = new Button(parent, SWT.PUSH); + button.setText(label); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumWidth = 70; + button.setLayoutData(gd); + button.setData(new Integer(id)); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + Integer val = (Integer) event.widget.getData(); + if (val != IDialogConstants.OK_ID) { + setReturnValue(null); + CreateSessionDialog.this.getShell().dispose(); + } else { + Text focusField = null; + List errorMessages = new ArrayList(); + String subject = subjectTF.getText().trim(); + String err = validateVenueName(); + String name = nameTF.getText(); + if (err != null) { + focusField = nameTF; + errorMessages.add(err); + } + + if (focusField == null) { + CreateSessionData result = new CreateSessionData(); + result.setName(name); + result.setSubject(subject); + result.setCollaborationSessioh(sharedSessionDisplay + .getSelection()); + if (inviteUsers == null) { + result.setInviteUsers(false); + } else { + result.setInviteUsers(inviteUsers.getSelection()); + result.setInviteMessage(inviteMessageTF.getText()); + } + + IVenueSession session = null; + try { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (result.isCollaborationSession()) { + session = connection.createCollaborationVenue( + result.getName(), result.getSubject()); + ISharedDisplaySession displaySession = (ISharedDisplaySession) session; + SharedDisplaySessionMgr.joinSession( + displaySession, + SharedDisplayRole.DATA_PROVIDER, null); + } else { + session = connection.createTextOnlyVenue( + result.getName(), result.getSubject()); + } + result.setSessionId(session.getSessionId()); + setReturnValue(result); + CreateSessionDialog.this.getShell().dispose(); + } catch (CollaborationException ex) { + statusHandler.handle(Priority.ERROR, + "Session Creation Error", ex); + event.doit = false; + setReturnValue(null); + } + } else { + StringBuilder sb = new StringBuilder(); + String prefix = ""; + for (String msg : errorMessages) { + sb.append(prefix).append(msg); + prefix = "\n"; + } + statusHandler.handle(Priority.ERROR, + "Session Creation Error"); + event.doit = false; + setReturnValue(null); + focusField.setFocus(); + focusField.selectAll(); + } + } + } + }); + if (defaultButton) { + Shell shell = parent.getShell(); + if (shell != null) { + shell.setDefaultButton(button); + } + } + return button; + } + + private String validateVenueName() { + String name = nameTF.getText().trim(); + nameTF.setText(name); + String err = null; + if (name.length() <= 0) { + err = "Must have session name."; + } else if (false) { + // TODO Above else make it a test for invalid characters. + err = "Name contains invalid characters."; + } else { + Collection info = CollaborationConnection + .getConnection().getVenueInfo(); + for (IVenueInfo i : info) { + if (name.equals(i.getVenueName())) { + err = "Session already exists. Pick a different name."; + break; + } + } + } + return err; + } + + private void enableOrDisableSharedDisplays() { + boolean sharedSessionsEnabled = Activator + .getDefault() + .getPreferenceStore() + .getBoolean( + CollabPrefConstants.HttpCollaborationConfiguration.P_SESSION_CONFIGURED); + this.sharedSessionDisplay.setSelection(sharedSessionsEnabled); + this.sharedSessionDisplay.setEnabled(sharedSessionsEnabled); + } + +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/IUserSelector.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/IUserSelector.java new file mode 100644 index 0000000000..b6a153993c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/IUserSelector.java @@ -0,0 +1,45 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import org.eclipse.ecf.core.user.IUser; + +/** + * Defines method for retrieving selected users. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 6, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public interface IUserSelector { + + public IUser[] getSelectedUsers(); + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/InviteDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/InviteDialog.java new file mode 100644 index 0000000000..571cc906a1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/InviteDialog.java @@ -0,0 +1,228 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +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.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.viz.ui.dialogs.CaveSWTDialogBase; + +/** + * + * Invite dialog. This is a custom dialog that will handle really long messages. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 14, 2012            lvenable     Initial creation.
+ * 
+ * 
+ * + * @author lvenable + * @version 1.0 + */ +public class InviteDialog extends CaveSWTDialogBase { + + /** Main composite. */ + private Composite mainComp; + + private String inviter; + + private String subject; + + private String room; + + private String inviteText; + + private String message; + + private Font font; + + /** + * Constructor. + * + * @param parentShell + * Parent shell. + * @param title + * Title for the dialog. + * @param labelStr + * Test to put in the label for the message text control. + * @param messageStr + * Message to be displayed. + * @param iconStyle + * Icon style to be displayed. + */ + public InviteDialog(Shell parentShell, String inviter, String subject, + String room, String inviteText, String message) { + super(parentShell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL + | SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL, CAVE.NONE); + setText("Session Invitation"); + + this.inviter = inviter; + this.subject = subject; + this.room = room; + this.inviteText = inviteText; + this.message = message; + + setReturnValue(Boolean.FALSE); + } + + @Override + protected Layout constructShellLayout() { + // Create the main layout for the shell. + GridLayout mainLayout = new GridLayout(1, false); + mainLayout.marginHeight = 2; + mainLayout.marginWidth = 2; + + return mainLayout; + } + + @Override + protected void initializeComponents(Shell shell) { + mainComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.horizontalSpacing = 0; + mainComp.setLayout(gl); + + createControls(); + createActionButtons(); + } + + /** + * Create the icon, and message controls. + */ + private void createControls() { + // Create a label and text control for the message + Composite labelTextComp = new Composite(mainComp, SWT.NONE); + labelTextComp.setLayout(new GridLayout(2, false)); + + GridData data = addLabel(labelTextComp, inviteText, true); + data.horizontalSpan = 2; + + addLabel(labelTextComp, "Inviter: ", true); + addLabel(labelTextComp, inviter, false); + addLabel(labelTextComp, "Room: ", true); + addLabel(labelTextComp, room, false); + if (subject != null && subject.isEmpty() == false) { + addLabel(labelTextComp, "Subject: ", true); + addLabel(labelTextComp, subject, false); + } + + if (message != null && message.isEmpty() == false) { + StyledText text = new StyledText(labelTextComp, SWT.MULTI + | SWT.BORDER | SWT.V_SCROLL); + text.setBackground(Display.getCurrent().getSystemColor( + SWT.COLOR_WIDGET_BACKGROUND)); + text.setText(message); + text.setEditable(false); + text.setWordWrap(true); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.widthHint = 350; + gd.heightHint = 100; + gd.horizontalSpan = 2; + text.setLayoutData(gd); + } + font.dispose(); + } + + /** + * Adds a label to the specified composite with bold or not bold heading + * text + * + * @param comp + * @param text + * @param heading + * @return + */ + private GridData addLabel(Composite comp, String text, boolean heading) { + GridData gd = null; + Label label = new Label(comp, SWT.WRAP); + label.setText(text); + if (font == null) { + FontData[] fontData = label.getFont().getFontData(); + fontData[0].setStyle(SWT.BOLD); + font = new Font(Display.getCurrent(), fontData[0]); + } + if (heading) { + gd = new GridData(SWT.LEFT, SWT.NONE, false, false); + label.setFont(font); + } else { + gd = new GridData(SWT.LEFT, SWT.NONE, true, true); + gd.widthHint = 300; + } + label.setLayoutData(gd); + return gd; + } + + /** + * Create the actions buttons. + */ + private void createActionButtons() { + Composite actionButtonComp = new Composite(mainComp, SWT.NONE); + actionButtonComp.setLayout(new GridLayout(2, false)); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.horizontalSpan = 2; + actionButtonComp.setLayoutData(gd); + + int btnWidth = 80; + gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false); + gd.widthHint = btnWidth; + Button okBtn = new Button(actionButtonComp, SWT.PUSH); + okBtn.setText("Join"); + okBtn.setLayoutData(gd); + okBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setReturnValue(Boolean.TRUE); + close(); + } + }); + + gd = new GridData(SWT.LEFT, SWT.DEFAULT, true, false); + gd.widthHint = btnWidth; + Button cancelBtn = new Button(actionButtonComp, SWT.PUSH); + cancelBtn.setText("Cancel"); + cancelBtn.setLayoutData(gd); + cancelBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + setReturnValue(Boolean.FALSE); + close(); + } + }); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/SiteColorInformation.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/SiteColorInformation.java new file mode 100644 index 0000000000..742dd3052e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/SiteColorInformation.java @@ -0,0 +1,173 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.eclipse.swt.graphics.RGB; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 16, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.NONE) +public class SiteColorInformation { + + @XmlElement + List colors; + + /** + * @return the colors + */ + public List getColors() { + return colors; + } + + /** + * @param colors + * the colors to set + */ + public void setColors(List colors) { + this.colors = colors; + } + + @XmlAccessorType(XmlAccessType.NONE) + public static class SiteColor { + + @XmlAttribute + private String site; + + @XmlAttribute + private int red; + + @XmlAttribute + private int green; + + @XmlAttribute + private int blue; + + public SiteColor() { + + } + + /** + * @return the site + */ + public String getSite() { + return site; + } + + /** + * @param site + * the site to set + */ + public void setSite(String site) { + this.site = site; + } + + /** + * @return the red + */ + public int getRed() { + return red; + } + + /** + * @param red + * the red to set + */ + public void setRed(int red) { + this.red = red; + } + + /** + * @return the green + */ + public int getGreen() { + return green; + } + + /** + * @param green + * the green to set + */ + public void setGreen(int green) { + this.green = green; + } + + /** + * @return the blue + */ + public int getBlue() { + return blue; + } + + /** + * @param blue + * the blue to set + */ + public void setBlue(int blue) { + this.blue = blue; + } + + public RGB getColor() { + return new RGB(red, green, blue); + } + + public void setColor(RGB rgb) { + red = rgb.red; + green = rgb.green; + blue = rgb.blue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (obj instanceof SiteColor == false) { + return false; + } else { + return this.getSite().equals(((SiteColor) obj).getSite()); + } + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/SiteConfigurationManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/SiteConfigurationManager.java new file mode 100644 index 0000000000..7c2b07f0de --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/SiteConfigurationManager.java @@ -0,0 +1,334 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManager; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation.SiteConfig; +import com.raytheon.uf.viz.collaboration.ui.SiteColorInformation.SiteColor; + +/** + * Parse a file to grab attributes about a user + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 12, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ +public class SiteConfigurationManager { + + private static SiteConfigInformation instance; + + private static SiteConfigInformation userInstance; + + private static SiteColorInformation colorInfo; + + /** + * Go to the config.xml file and grab the user information, for use in + * determining what kind of user you are in collaboration + * + * @return + */ + public static synchronized SiteConfigInformation getSiteConfigInformation() { + if (instance == null) { + PathManager pm = (PathManager) PathManagerFactory.getPathManager(); + Map files = pm + .getTieredLocalizationFile(LocalizationType.CAVE_STATIC, + "collaboration" + File.separator + "config.xml"); + + LocalizationLevel[] levels = LocalizationLevel.values(); + for (int i = levels.length - 1; i >= 0 && instance == null; --i) { + LocalizationLevel level = levels[i]; + if (level.isSystemLevel() || level == LocalizationLevel.SITE) { + LocalizationFile file = files.get(level); + if (file != null) { + InputStream in = null; + try { + in = file.openInputStream(); + JAXBContext context = JAXBContext + .newInstance(SiteConfigInformation.class); + Unmarshaller unmarshaller = context + .createUnmarshaller(); + SiteConfigInformation info = (SiteConfigInformation) unmarshaller + .unmarshal(in); + if (isValid(info)) { + instance = info; + } else { + Activator.statusHandler + .handle(Priority.PROBLEM, + "Misconfigured config.xml file at " + + level + + " level. " + + "Does not contain required " + + SiteConfigInformation.SITE_NAME + + " and " + + SiteConfigInformation.ROLE_NAME + + " attributes."); + } + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + if (in != null) { + try { + in.close(); + } catch (IOException e) { + Activator.statusHandler.handle( + Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + } + } + } + return instance; + } + + /** + * Write the colorInfo.xml file out to user localization so that the user + * can retrieve it on CAVE restart + * + * @param information + */ + public static void writeSiteColorInformation( + SiteColorInformation information) { + colorInfo = information; + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext lContext = pathMgr.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = pathMgr.getLocalizationFile(lContext, + "collaboration" + File.separator + "colorInfo.xml"); + try { + JAXBContext context = JAXBContext + .newInstance(SiteColorInformation.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + new Boolean(true)); + marshaller.marshal(information, file.getFile()); + file.save(); + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + /** + * Allows users to have their own extra configured sites, but does not check + * for validity as we don't have to have a role or a site specified, only + * subscribed sites + */ + private static synchronized void readUserSiteConfigInformation() { + LocalizationFile file = getUserConfigFile(); + if (file != null && file.exists()) { + InputStream in = null; + try { + in = file.openInputStream(); + JAXBContext context = JAXBContext + .newInstance(SiteConfigInformation.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + SiteConfigInformation info = (SiteConfigInformation) unmarshaller + .unmarshal(in); + userInstance = info; + } catch (JAXBException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } catch (LocalizationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + public static void writeUserSiteConfigInformation( + SiteConfigInformation information) { + userInstance = information; + LocalizationFile file = getUserConfigFile(); + try { + JAXBContext context = JAXBContext + .newInstance(SiteConfigInformation.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, + new Boolean(true)); + marshaller.marshal(information, file.getFile()); + file.save(); + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + /** + * Shortcut method for retrieving the user configuration file + * + * @return + */ + private static LocalizationFile getUserConfigFile() { + IPathManager pathMgr = PathManagerFactory.getPathManager(); + LocalizationContext lContext = pathMgr.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = pathMgr.getLocalizationFile(lContext, + "collaboration" + File.separator + "config.xml"); + return file; + } + + /** + * Instantiate the colorInfo object so that the colors can be read in from + * the colorInfo.xml file and retrieved from localization + * + * @return + */ + public static SiteColorInformation getSiteColorInformation() { + if (colorInfo == null) { + PathManager pm = (PathManager) PathManagerFactory.getPathManager(); + Map files = pm + .getTieredLocalizationFile(LocalizationType.CAVE_STATIC, + "collaboration" + File.separator + "colorInfo.xml"); + LocalizationLevel[] levels = LocalizationLevel.values(); + + for (int i = levels.length - 1; i >= 0 && colorInfo == null; --i) { + LocalizationLevel level = levels[i]; + if (level == LocalizationLevel.SITE + || level == LocalizationLevel.USER) { + LocalizationFile file = files.get(level); + if (file != null) { + InputStream in = null; + try { + in = file.openInputStream(); + JAXBContext context = JAXBContext + .newInstance(SiteColorInformation.class); + Unmarshaller unmarshaller = context + .createUnmarshaller(); + colorInfo = (SiteColorInformation) unmarshaller + .unmarshal(in); + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + if (in != null) { + try { + in.close(); + } catch (IOException e) { + Activator.statusHandler.handle( + Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + } + } + } + return colorInfo; + } + + /** + * @param info + * @return + */ + private static boolean isValid(SiteConfigInformation info) { + if (info != null) { + for (SiteConfig i : info.getConfig()) { + if (i.getSite() != null && !i.getSite().isEmpty() + && i.getRoles() != null && i.getRoles().length > 0) { + return true; + } + } + } + return false; + } + + public static List getSubscribeList(String site) { + List subscribed = new ArrayList(); + for (SiteConfig config : instance.getConfig()) { + if (config.getSite().equals(site)) { + subscribed = Arrays.asList(config.getSubscribedSites()); + break; + } + } + return subscribed; + } + + /** + * Reads and sets the user subscribe list + * + * @return + */ + public static List getUserSubscribeList() { + if (userInstance == null) { + readUserSiteConfigInformation(); + } + List subscribed = new ArrayList(); + if (userInstance != null) { + for (SiteConfig config : userInstance.getConfig()) { + if (config.getSubscribedSites() != null) { + subscribed = new ArrayList(); + for (String item : config.getSubscribedSites()) { + subscribed.add(item); + } + break; + } + } + } + return subscribed; + } + + public static List getSiteColors() { + SiteColorInformation colorInfo = getSiteColorInformation(); + if (colorInfo != null) { + return getSiteColorInformation().getColors(); + } else { + return null; + } + } + + public static void nullifySiteConfigInstance() { + instance = null; + userInstance = null; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UserSearchDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UserSearchDialog.java new file mode 100644 index 0000000000..9958aa92eb --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UserSearchDialog.java @@ -0,0 +1,310 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.core.util.ECFException; +import org.eclipse.ecf.presence.search.ICriteria; +import org.eclipse.ecf.presence.search.ICriterion; +import org.eclipse.ecf.presence.search.IResult; +import org.eclipse.ecf.presence.search.ISearch; +import org.eclipse.ecf.presence.search.IUserSearchManager; +import org.eclipse.ecf.presence.search.UserSearchException; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +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.layout.RowData; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.actions.AddToGroupAction; +import com.raytheon.uf.viz.collaboration.ui.actions.CreateSessionAction; +import com.raytheon.uf.viz.collaboration.ui.actions.InviteAction; +import com.raytheon.uf.viz.collaboration.ui.actions.PeerToPeerChatAction; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Provides a dialog for searching for users within collaboration in viz. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 27, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class UserSearchDialog extends CaveSWTDialog implements IUserSelector { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(UserSearchDialog.class); + + private Text searchText; + + private Combo fieldCombo; + + private Table resultTable; + + public UserSearchDialog(Shell parentShell) { + super(parentShell, SWT.RESIZE | SWT.DIALOG_TRIM); + setText("User Search"); + } + + @Override + protected void initializeComponents(Shell shell) { + initializeSearchBar(shell); + initializeResultsTable(shell); + initializeButtonBar(shell); + } + + private void initializeSearchBar(Shell shell) { + Composite entryComp = new Composite(shell, SWT.NONE); + entryComp + .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + entryComp.setLayout(new GridLayout(3, false)); + searchText = new Text(entryComp, SWT.BORDER); + GridData gridData = new GridData(200, SWT.DEFAULT); + gridData.grabExcessHorizontalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + searchText.setLayoutData(gridData); + searchText.addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + search(); + } + } + + }); + + IUserSearchManager manager = CollaborationConnection.getConnection() + .getPresenceContainerAdapter().getUserSearchManager(); + fieldCombo = new Combo(entryComp, SWT.DROP_DOWN | SWT.READ_ONLY); + fieldCombo.add("All"); + try { + for (String field : manager.getUserPropertiesFields()) { + fieldCombo.add(field); + } + fieldCombo.select(0); + } catch (ECFException e1) { + statusHandler + .handle(Priority.PROBLEM, e1.getLocalizedMessage(), e1); + } + Button searchButton = new Button(entryComp, SWT.PUSH); + searchButton.setText("Search"); + searchButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + search(); + } + + }); + } + + private void initializeResultsTable(Shell shell) { + Composite tableComp = new Composite(shell, SWT.NONE); + GridData gridData = new GridData(SWT.DEFAULT, 200); + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + tableComp.setLayoutData(gridData); + resultTable = new Table(tableComp, SWT.BORDER | SWT.V_SCROLL + | SWT.H_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); + resultTable.setHeaderVisible(true); + resultTable.setLinesVisible(true); + TableColumn nameColumn = new TableColumn(resultTable, SWT.LEFT); + nameColumn.setText("Full Name"); + TableColumn idColumn = new TableColumn(resultTable, SWT.LEFT); + idColumn.setText("User ID"); + + TableColumnLayout tcl = new TableColumnLayout(); + tableComp.setLayout(tcl); + tcl.setColumnData(nameColumn, new ColumnWeightData(40)); + tcl.setColumnData(idColumn, new ColumnWeightData(60)); + + MenuManager menuMgr = new MenuManager(); + menuMgr.setRemoveAllWhenShown(true); + menuMgr.addMenuListener(new IMenuListener() { + + @Override + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + + }); + Menu menu = menuMgr.createContextMenu(resultTable); + resultTable.setMenu(menu); + } + + private void initializeButtonBar(Shell shell) { + Composite buttonComp = new Composite(shell, SWT.NONE); + buttonComp.setLayoutData(new GridData(SWT.RIGHT, SWT.NONE, false, + false, 1, 1)); + RowLayout layout = new RowLayout(SWT.HORIZONTAL); + layout.pack = false; + buttonComp.setLayout(layout); + + Button closeButton = new Button(buttonComp, SWT.PUSH); + closeButton.setText("Close"); + closeButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + + }); + closeButton.setLayoutData(new RowData(90, SWT.DEFAULT)); + } + + private void fillContextMenu(IMenuManager manager) { + TableItem[] selection = resultTable.getSelection(); + if (selection == null || selection.length == 0) { + return; + } + IUser[] users = new IUser[selection.length]; + for (int i = 0; i < users.length; i += 1) { + users[i] = (IUser) selection[i].getData(); + } + if (users.length == 1) { + Action p2pAction = new PeerToPeerChatAction(users[0]); + if (p2pAction.isEnabled()) { + manager.add(p2pAction); + } + } + Action inviteAction = new InviteAction(users); + if (inviteAction.isEnabled()) { + manager.add(inviteAction); + } + if (manager.getItems().length > 0) { + manager.add(new Separator()); + } + + manager.add(new CreateSessionAction(this)); + manager.add(new AddToGroupAction(users)); + } + + private void search() { + List results = new ArrayList(); + List keys = new ArrayList(); + if (fieldCombo.getText().equals("All")) { + for (String string : fieldCombo.getItems()) { + if (!string.equals("All")) { + keys.add(string); + } + } + } else { + keys.add(fieldCombo.getText()); + } + for (String key : keys) { + IUserSearchManager manager = CollaborationConnection + .getConnection().getPresenceContainerAdapter() + .getUserSearchManager(); + ICriterion criterion = manager.createRestriction().eq(key, + searchText.getText(), true); + ICriteria criteria = manager.createCriteria(); + criteria.add(criterion); + try { + ISearch search = manager.search(criteria); + for (Object result : search.getResultList().getResults()) { + if (result instanceof IResult) { + IUser user = ((IResult) result).getUser(); + results.add(user); + } + } + } catch (UserSearchException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + Set uniqueIds = new HashSet(); + resultTable.removeAll(); + if (results.size() > 0) { + for (IUser user : results) { + String id = user.getID().getName(); + if (!uniqueIds.contains(id)) { + TableItem ti = new TableItem(resultTable, SWT.NONE); + ti.setText(0, user.getName()); + ti.setText(1, id); + ti.setData(user); + uniqueIds.add(id); + } + } + resultTable.setEnabled(true); + } else { + TableItem ti = new TableItem(resultTable, SWT.NONE); + ti.setText("No users found."); + resultTable.setEnabled(false); + } + } + + @Override + public IUser[] getSelectedUsers() { + Set selectedUsers = new HashSet(); + TableItem[] selection = resultTable.getSelection(); + + if (selection != null && selection.length > 0) { + IUser[] users = new IUser[selection.length]; + for (int i = 0; i < users.length; i += 1) { + IUser user = (IUser) selection[i].getData(); + selectedUsers.add(user); + } + } + return selectedUsers.toArray(new IUser[selectedUsers.size()]); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeContentProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeContentProvider.java new file mode 100644 index 0000000000..4e62d7810f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeContentProvider.java @@ -0,0 +1,225 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer; +import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class UsersTreeContentProvider implements ITreeContentProvider { + + private Viewer viewer; + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + @Override + public void dispose() { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface + * .viewers.Viewer, java.lang.Object, java.lang.Object) + */ + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + this.viewer = viewer; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang. + * Object) + */ + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof SessionGroupContainer) { + SessionGroupContainer group = (SessionGroupContainer) inputElement; + return group.getObjects().toArray(); + } else if (inputElement instanceof CollaborationGroupContainer) { + CollaborationGroupContainer cont = (CollaborationGroupContainer) inputElement; + return cont.getObjects().toArray(); + } else { + return new Object[0]; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang. + * Object) + */ + @Override + public Object[] getChildren(Object parentElement) { + // the only things that can have children are the sessions item or the + // groups items + if (parentElement instanceof SessionGroupContainer) { + SessionGroupContainer cont = (SessionGroupContainer) parentElement; + return cont.getObjects().toArray(); + } else if (parentElement instanceof IRosterGroup) { + IRosterGroup group = (IRosterGroup) parentElement; + List result = new ArrayList(); + UserId localUser = CollaborationConnection.getConnection() + .getUser(); + Collection entries = group.getEntries(); + synchronized (entries) { + entries = new ArrayList(entries); + } + for (Object obj : entries) { + if (obj instanceof IRosterEntry) { + IUser user = ((IRosterEntry) obj).getUser(); + if (!localUser.isSameUser(user.getID().getName())) { + result.add(user); + } + } + } + return result.toArray(); + } else if (parentElement instanceof LocalGroup) { + List result = new ArrayList(); + LocalGroup group = (LocalGroup) parentElement; + UserId localUser = CollaborationConnection.getConnection() + .getUser(); + for (IUser user : group.getUsers()) { + if (!localUser.isSameUser(user.getID().getName())) { + result.add(user); + } + } + return result.toArray(); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object + * ) + */ + @Override + public Object getParent(Object element) { + // TODO Auto-generated method stub + return null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang. + * Object) + */ + @Override + public boolean hasChildren(Object element) { + boolean hasChildren = false; + if (element instanceof IRosterGroup) { + IRosterGroup group = (IRosterGroup) element; + UserId localUser = CollaborationConnection.getConnection() + .getUser(); + Collection entries = group.getEntries(); + synchronized (entries) { + entries = new ArrayList(entries); + } + for (Object obj : entries) { + if (obj instanceof IRosterEntry) { + IUser user = ((IRosterEntry) obj).getUser(); + if (!localUser.isSameUser(user.getID().getName())) { + hasChildren = true; + break; + } + } + } + } else if (element instanceof SessionGroupContainer) { + SessionGroupContainer cont = (SessionGroupContainer) element; + if (cont.getObjects() != null && cont.getObjects().size() > 0) { + hasChildren = true; + } else { + hasChildren = false; + } + } else if (element instanceof LocalGroup) { + UserId localUser = CollaborationConnection.getConnection() + .getUser(); + List userNames = ((LocalGroup) element).getUserNames(); + for (String userName : userNames) { + if (!localUser.isSameUser(userName)) { + hasChildren = true; + break; + } + } + } + + // need to check whether items are filtered out so we don't get + // empty groups that have an arrow, masking that nothing is in them + ViewerFilter[] filters = ((TreeViewer) viewer).getFilters(); + if (hasChildren && filters.length > 0) { + Object[] children = getChildren(element); + for (int i = 0; i < filters.length; ++i) { + children = filters[i].filter(viewer, element, children); + if (children.length == 0) { + return false; + } + } + return children.length > 0; + } + return hasChildren; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeFilter.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeFilter.java new file mode 100644 index 0000000000..c5e6e180eb --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeFilter.java @@ -0,0 +1,93 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerFilter; + +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 13, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class UsersTreeFilter extends ViewerFilter { + private String currentText; + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers + * .Viewer, java.lang.Object, java.lang.Object) + */ + @Override + public boolean select(Viewer viewer, Object parentElement, Object element) { + boolean retVal = true; + if (currentText != null) { + String labelText = ((ILabelProvider) ((StructuredViewer) viewer) + .getLabelProvider()).getText(element); + if (labelText.equals(currentText)) { + viewer.setSelection(new StructuredSelection(element)); + } + if (element instanceof IUser && !(element instanceof UserId)) { + String[] words = getWords(currentText); + for (String word : words) { + if (!labelText.toUpperCase().contains(word.toUpperCase())) { + retVal = false; + break; + } + } + } else { + retVal = true; + } + } + return retVal; + } + + private String[] getWords(String text) { + return text.trim().split("\\s+"); + } + + /** + * @param currentText + * the currentText to set + */ + public void setCurrentText(String currentText) { + this.currentText = currentText; + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java new file mode 100644 index 0000000000..65b40dc5c9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeLabelProvider.java @@ -0,0 +1,242 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class UsersTreeLabelProvider extends ColumnLabelProvider { + + private AbstractUserLabelProvider userLabelProvider = new AbstractUserLabelProvider() { + + @Override + protected IPresence getPresence(IUser user) { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + return null; + } + if (user instanceof UserId) { + return connection.getPresence(); + } + return connection.getContactsManager().getPresence(user); + } + }; + + private List listeners; + + private Map imageMap; + + private Font boldFont = null; + + public UsersTreeLabelProvider() { + listeners = new ArrayList(); + imageMap = new HashMap(); + } + + @Override + public Image getImage(Object element) { + if (Activator.getDefault() == null) { + return null; + } + String key = ""; + if (element instanceof IUser) { + return userLabelProvider.getImage(element); + } else if (element instanceof IRosterGroup) { + key = "group"; + } else if (element instanceof IVenueSession) { + // key = "session_group"; + } else if (element instanceof SessionGroupContainer) { + key = "session_group"; + } else if (element instanceof LocalGroup) { + key = "local_group"; + } + + if (imageMap.get(key) == null && !key.equals("")) { + imageMap.put(key, CollaborationUtils.getNodeImage(key)); + } + return imageMap.get(key); + } + + @Override + public String getText(Object element) { + if (element instanceof IRosterGroup) { + return ((IRosterGroup) element).getName(); + } else if (element instanceof SessionGroupContainer) { + return "Active Sessions"; + } else if (element instanceof UserId) { + UserId user = (UserId) element; + IPresence presence = userLabelProvider.getPresence(user); + String fullName = user.getName(); + if (presence != null) { + if (presence.getProperties() != null) { + Object site = presence.getProperties().get( + SiteConfigInformation.SITE_NAME); + if (site != null && !site.toString().isEmpty()) { + fullName += " - " + site; + } + Object role = presence.getProperties().get( + SiteConfigInformation.ROLE_NAME); + if (role != null && !role.toString().isEmpty()) { + fullName += " - " + role; + } + } + } + return fullName + " - " + user.getHost(); + } else if (element instanceof IVenueSession) { + if (((IVenueSession) element).getVenue() == null) { + return null; + } + return ((IVenueSession) element).getVenue().getInfo() + .getVenueDescription(); + } else if (element instanceof LocalGroup) { + return ((LocalGroup) element).getName(); + } else if (element instanceof IUser) { + return userLabelProvider.getText(element); + } + return null; + } + + @Override + public Font getFont(Object element) { + if (element instanceof IRosterGroup + || element instanceof SessionGroupContainer + || element instanceof LocalGroup) { + // for this case do nothing, as it is not the top level of + // session groups + if (boldFont == null) { + Font currFont = Display.getCurrent().getSystemFont(); + boldFont = new Font(Display.getCurrent(), currFont.toString(), + currFont.getFontData()[0].getHeight(), SWT.BOLD); + } + return boldFont; + } + return null; + } + + /** + * Gets the tooltip text on the tree that this is a label provider for + */ + @Override + public String getToolTipText(Object element) { + StringBuilder builder = new StringBuilder(); + if (element instanceof IUser) { + return userLabelProvider.getToolTipText(element); + } + // builds the tooltip text for the session group + // portion of the view + else if (element instanceof IVenueSession) { + IVenueSession sessGroup = (IVenueSession) element; + IVenueInfo info = sessGroup.getVenue().getInfo(); + builder.append("ID: ").append(info.getVenueID()); + builder.append("\nName: ").append(info.getVenueDescription()) + .append("\n"); + builder.append("Subject: ").append(info.getVenueSubject()) + .append("\n"); + builder.append("Participants: ").append(info.getParticipantCount()); + return builder.toString(); + } else { + return null; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.CellLabelProvider#getToolTipStyle(java.lang + * .Object) + */ + @Override + public int getToolTipStyle(Object object) { + return SWT.SHADOW_OUT; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.CellLabelProvider#getToolTipShift(java.lang + * .Object) + */ + @Override + public Point getToolTipShift(Object object) { + return new Point(5, 5); + } + + @Override + public void addListener(ILabelProviderListener listener) { + listeners.add(listener); + } + + @Override + public void removeListener(ILabelProviderListener listener) { + listeners.remove(listener); + } + + @Override + public void dispose() { + userLabelProvider.dispose(); + for (String key : imageMap.keySet()) { + imageMap.get(key).dispose(); + } + if (boldFont != null && !boldFont.isDisposed()) { + boldFont.dispose(); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeViewerSorter.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeViewerSorter.java new file mode 100644 index 0000000000..00a2733f6f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/UsersTreeViewerSorter.java @@ -0,0 +1,130 @@ +package com.raytheon.uf.viz.collaboration.ui; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.ecf.presence.roster.IRosterGroup; +import org.eclipse.ecf.presence.roster.IRosterItem; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; + +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class UsersTreeViewerSorter extends ViewerSorter { + + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if (e1 == e2) { + return 0; + } + + // Make login user top node + if (e1 instanceof UserId) { + return -1; + } + + if (e2 instanceof UserId) { + return 1; + } + + // session group before all other types but login user. + if (e1 instanceof SessionGroupContainer) { + if ((e2 instanceof SessionGroupContainer) == false) { + return -1; + } + } else if (e2 instanceof SessionGroupContainer) { + return 1; + } + + // Groups before users. + if (e1 instanceof IRosterGroup) { + if (!(e2 instanceof IRosterGroup)) { + return -1; + } + } else if (e1 instanceof IRosterGroup) { + return 1; + } + if (e1 instanceof IRosterItem && e2 instanceof IRosterItem) { + // Either both are groups or both are users. + if (e1 instanceof IRosterGroup && e2 instanceof IRosterGroup) { + return ((IRosterGroup) e1).getName().compareTo( + ((IRosterGroup) e2).getName()); + } else if (e1 instanceof IRosterEntry && e2 instanceof IRosterEntry) { + String name; + String otherName; + IRosterEntry entry = (IRosterEntry) e1; + IRosterEntry otherEntry = (IRosterEntry) e2; + if (entry.getUser().getName() != null + && !entry.getUser().getName().isEmpty()) { + name = entry.getUser().getName(); + } else { + name = entry.getName(); + } + + if (otherEntry.getUser().getName() != null + && !otherEntry.getUser().getName().isEmpty()) { + otherName = otherEntry.getUser().getName(); + } else { + otherName = otherEntry.getName(); + } + return name.compareTo(otherName); + } + } else if (e1 instanceof IVenueSession && e2 instanceof IVenueSession) { + if (((IVenueSession) e1).getVenue() == null + || ((IVenueSession) e1).getVenue() == null) { + return 0; + } + return ((IVenueSession) e1).getVenue().toString() + .compareTo(((IVenueSession) e2).getVenue().toString()); + } + if (e1 instanceof LocalGroup) { + if (!(e2 instanceof LocalGroup)) { + return -1; + } + } else if (e1 instanceof LocalGroup) { + return 1; + } + if (e1 instanceof LocalGroup && e2 instanceof LocalGroup) { + return ((LocalGroup) e1).getName().compareTo( + ((LocalGroup) e2).getName()); + } + return 0; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/AddToGroupAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/AddToGroupAction.java new file mode 100644 index 0000000000..5926dbe13a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/AddToGroupAction.java @@ -0,0 +1,144 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CreateGroupDialog; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Add a user or users to a local group. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class AddToGroupAction extends Action { + + private final String group; + + private final IUser[] users; + + /** + * This action will create a menu of groups to which the users will be added + * + * @param users + */ + public AddToGroupAction(IUser... users) { + super("Add To Group...", IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "add_group.gif")); + this.users = users; + this.group = null; + this.setMenuCreator(new MenuCreator()); + } + + public AddToGroupAction(String group, IUser... users) { + super(group, IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "local_group.gif")); + this.group = group; + this.users = users; + } + + @Override + public void run() { + String group = this.group; + if (group == null) { + CreateGroupDialog dialog = new CreateGroupDialog(Display + .getCurrent().getActiveShell()); + dialog.open(); + group = dialog.getNewGroup(); + if (group == null) { + return; + } + } + for (IUser user : users) { + CollaborationConnection.getConnection().getContactsManager() + .addToLocalGroup(group, user); + } + } + + private class MenuCreator implements IMenuCreator { + + private Menu menu; + + @Override + public void dispose() { + menu.dispose(); + } + + @Override + public Menu getMenu(Control parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + @Override + public Menu getMenu(Menu parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + private void fill() { + ContactsManager contactsMgr = CollaborationConnection + .getConnection().getContactsManager(); + List groups = contactsMgr.getLocalGroups(); + List usedGroups = new ArrayList(groups); + for (IUser user : users) { + usedGroups.retainAll(contactsMgr.getLocalGroups(user)); + } + groups.removeAll(usedGroups); + for (LocalGroup group : groups) { + Action action = new AddToGroupAction(group.getName(), users); + IContributionItem contrib = new ActionContributionItem(action); + contrib.fill(menu, -1); + } + Action action = new CreateGroupAction(users); + IContributionItem contrib = new ActionContributionItem(action); + contrib.fill(menu, -1); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ArchiveViewerAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ArchiveViewerAction.java new file mode 100644 index 0000000000..6b31f2a7a7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ArchiveViewerAction.java @@ -0,0 +1,99 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.provider.Tools; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.session.SessionMsgArchive; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Open the Log View + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ArchiveViewerAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ArchiveViewerAction.class); + + private final String sessionName; + + public ArchiveViewerAction() { + super("View Log...", IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "log.gif")); + sessionName = null; + setEnabled(CollaborationConnection.getConnection() != null); + } + + public ArchiveViewerAction(IUser user) { + super("View Log...", IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "log.gif")); + sessionName = Tools.parseName(user.getID().getName()); + } + + public ArchiveViewerAction(IVenueSession session) { + super("View Log...", IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "log.gif")); + sessionName = session.getVenue().getInfo().getVenueDescription(); + } + + @Override + public void run() { + UserId user = CollaborationConnection.getConnection().getUser(); + String logDir = SessionMsgArchive.getLogFilePath(user.getHost(), + user.getName(), sessionName); + + try { + CaveWorkbenchPageManager + .getActiveInstance() + .showView( + "com.raytheon.uf.viz.collaboration.ui.session.SessionMsgArchiveView", + logDir, IWorkbenchPage.VIEW_ACTIVATE); + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to open Collaboration Log View", e); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeFontAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeFontAction.java new file mode 100644 index 0000000000..3294fe6bf7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeFontAction.java @@ -0,0 +1,72 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FontDialog; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Open change font dialog + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 6, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ChangeFontAction extends Action { + + public ChangeFontAction() { + super("Change Font...", IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "font.gif")); + } + + @Override + public void run() { + FontDialog dialog = new FontDialog(Display.getCurrent() + .getActiveShell()); + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + FontData data = PreferenceConverter.getFontData(store, "font"); + dialog.setFontList(new FontData[] { data }); + FontData postData = dialog.open(); + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (postData != null && connection != null) { + PreferenceConverter.setValue(store, "font", postData); + connection.postEvent(postData); + } + }; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangePasswordAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangePasswordAction.java new file mode 100644 index 0000000000..0afd148ae6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangePasswordAction.java @@ -0,0 +1,78 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.ChangePasswordDialog; + +/** + * Open change password dialog + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ChangePasswordAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ChangePasswordAction.class); + + public ChangePasswordAction() { + super("Change Password..."); + setEnabled(CollaborationConnection.getConnection() != null); + } + + @Override + public void run() { + ChangePasswordDialog dialog = new ChangePasswordDialog(Display + .getCurrent().getActiveShell()); + dialog.open(); + + Object result = dialog.getReturnValue(); + if (result != null) { + char[] password = result.toString().toCharArray(); + try { + CollaborationConnection.getConnection().getAccountManager() + .changePassword(password); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to change password", e); + } + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeRoleAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeRoleAction.java new file mode 100644 index 0000000000..60faac007d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeRoleAction.java @@ -0,0 +1,147 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.Map; + +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation.SiteConfig; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager; + +/** + * Change the role for the logged in user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ChangeRoleAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ChangeRoleAction.class); + + private final String role; + + public ChangeRoleAction() { + super("Change Role"); + this.role = null; + setMenuCreator(new MenuCreator()); + setEnabled(CollaborationConnection.getConnection() != null); + } + + public ChangeRoleAction(String role) { + super(role, Action.AS_RADIO_BUTTON); + this.role = role; + IPresence presence = CollaborationConnection.getConnection() + .getPresence(); + String currentRole = (String) presence.getProperties().get( + SiteConfigInformation.ROLE_NAME); + if (role.equals(currentRole)) { + setChecked(true); + } + } + + @Override + public void run() { + if (!this.isChecked()) { + return; + } + CollaborationConnection connection = CollaborationConnection + .getConnection(); + + IPresence presence = connection.getPresence(); + @SuppressWarnings("unchecked") + Map props = presence.getProperties(); + props.put(SiteConfigInformation.ROLE_NAME, role); + + try { + connection.getAccountManager().sendPresence(presence); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, "Error sending presence", e); + } + + } + + private static class MenuCreator implements IMenuCreator { + + private Menu menu; + + @Override + public void dispose() { + menu.dispose(); + } + + @Override + public Menu getMenu(Control parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + @Override + public Menu getMenu(Menu parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + private void fill() { + SiteConfigInformation siteInfo = SiteConfigurationManager + .getSiteConfigInformation(); + IPresence presence = CollaborationConnection.getConnection() + .getPresence(); + String currentSite = (String) presence.getProperties().get( + SiteConfigInformation.SITE_NAME); + for (SiteConfig config : siteInfo.getConfig()) { + if (config.getSite().equals(currentSite)) { + for (String role : config.getRoles()) { + Action action = new ChangeRoleAction(role); + IContributionItem contrib = new ActionContributionItem( + action); + contrib.fill(menu, -1); + } + } + } + } + }; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeSiteAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeSiteAction.java new file mode 100644 index 0000000000..639b92c552 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeSiteAction.java @@ -0,0 +1,144 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.Map; + +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation.SiteConfig; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager; +import com.raytheon.uf.viz.collaboration.ui.session.SubscribeList; + +/** + * Change the site for the logged in user + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ChangeSiteAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ChangeSiteAction.class); + + private final String site; + + public ChangeSiteAction() { + super("Change Site"); + this.site = null; + setMenuCreator(new MenuCreator()); + setEnabled(CollaborationConnection.getConnection() != null); + } + + public ChangeSiteAction(String site) { + super(site, Action.AS_RADIO_BUTTON); + this.site = site; + IPresence presence = CollaborationConnection.getConnection() + .getPresence(); + String currentSite = (String) presence.getProperties().get( + SiteConfigInformation.SITE_NAME); + if (site.equals(currentSite)) { + setChecked(true); + } + } + + @Override + public void run() { + if (!this.isChecked()) { + return; + } + CollaborationConnection connection = CollaborationConnection + .getConnection(); + + IPresence presence = connection.getPresence(); + @SuppressWarnings("unchecked") + Map props = presence.getProperties(); + props.put(SiteConfigInformation.SITE_NAME, site); + // now need to send the new subscribe list out to those who are + // listening for it + SubscribeList list = new SubscribeList(); + list.setEnabledSites(SiteConfigurationManager.getSubscribeList(site)); + connection.postEvent(list); + + try { + connection.getAccountManager().sendPresence(presence); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, "Error sending presence", e); + } + + } + + private static class MenuCreator implements IMenuCreator { + + private Menu menu; + + @Override + public void dispose() { + menu.dispose(); + } + + @Override + public Menu getMenu(Control parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + @Override + public Menu getMenu(Menu parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + private void fill() { + SiteConfigInformation siteInfo = SiteConfigurationManager + .getSiteConfigInformation(); + for (SiteConfig config : siteInfo.getConfig()) { + Action action = new ChangeSiteAction(config.getSite()); + IContributionItem contrib = new ActionContributionItem(action); + contrib.fill(menu, -1); + } + } + }; +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeStatusAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeStatusAction.java new file mode 100644 index 0000000000..93cc01f0bd --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeStatusAction.java @@ -0,0 +1,139 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Mode; +import org.eclipse.ecf.presence.Presence; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CollaborationUtils; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Change the status(Presence Mode) for the current user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 6, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ChangeStatusAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ChangeStatusAction.class); + + private final Mode mode; + + public ChangeStatusAction() { + super("Change Status", Action.AS_DROP_DOWN_MENU); + mode = null; + setMenuCreator(new MenuCreator()); + setEnabled(CollaborationConnection.getConnection() != null); + } + + public ChangeStatusAction(Mode mode) { + super(CollaborationUtils.formatMode(mode), Action.AS_RADIO_BUTTON); + this.mode = mode; + String iconName = mode.toString().replaceAll("\\s+", "_").toLowerCase() + + ".gif"; + setImageDescriptor(IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), iconName)); + IPresence presence = CollaborationConnection.getConnection() + .getPresence(); + if (mode.equals(presence.getMode())) { + setChecked(true); + } + } + + @Override + public void run() { + if (!this.isChecked()) { + return; + } + CollaborationConnection connection = CollaborationConnection + .getConnection(); + + IPresence presence = connection.getPresence(); + presence = new Presence(presence.getType(), presence.getStatus(), mode, + presence.getProperties()); + + try { + connection.getAccountManager().sendPresence(presence); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, "Error sending presence", e); + } + + } + + private static class MenuCreator implements IMenuCreator { + + private Menu menu; + + @Override + public void dispose() { + menu.dispose(); + } + + @Override + public Menu getMenu(Control parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + @Override + public Menu getMenu(Menu parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + private void fill() { + for (int index = 0; index < CollaborationUtils.statusModes.length; ++index) { + Action action = new ChangeStatusAction( + CollaborationUtils.statusModes[index]); + IContributionItem contrib = new ActionContributionItem(action); + contrib.fill(menu, -1); + } + } + }; + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeStatusMessageAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeStatusMessageAction.java new file mode 100644 index 0000000000..c597fc0c50 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ChangeStatusMessageAction.java @@ -0,0 +1,86 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.Presence; +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.login.ChangeStatusDialog; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; + +/** + * Change the status message for the current user. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 6, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ChangeStatusMessageAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(ChangeStatusMessageAction.class); + + public ChangeStatusMessageAction() { + super("Change Status Message..."); + setEnabled(CollaborationConnection.getConnection() != null); + } + + @Override + public void run() { + ChangeStatusDialog dialog = new ChangeStatusDialog(Display.getCurrent() + .getActiveShell()); + dialog.open(); + // I would expect the dialog to do this + String msg = Activator.getDefault().getPreferenceStore() + .getString(CollabPrefConstants.P_MESSAGE); + CollaborationConnection connection = CollaborationConnection + .getConnection(); + + IPresence presence = connection.getPresence(); + presence = new Presence(presence.getType(), msg, presence.getMode(), + presence.getProperties()); + + try { + connection.getAccountManager().sendPresence(presence); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, "Error sending presence", e); + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CollaborationGroupAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CollaborationGroupAction.java new file mode 100644 index 0000000000..3ec54b0106 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CollaborationGroupAction.java @@ -0,0 +1,86 @@ +package com.raytheon.uf.viz.collaboration.ui.actions; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CollaborationGroupView; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Action to open the group view, as well as the default chat room + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class CollaborationGroupAction extends AbstractHandler { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CollaborationGroupAction.class); + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + // this opens the collaboration group view + try { + new LoginAction().run(); + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + // user cancelled login + return event; + } + + CaveWorkbenchPageManager.getActiveInstance().showView( + CollaborationGroupView.ID); + + // if autojoin is selected (to join the default room) + if (Activator.getDefault().getPreferenceStore() + .getBoolean(CollabPrefConstants.AUTO_JOIN)) { + DisplayFeedAction displayFeed = new DisplayFeedAction(); + displayFeed.setChecked(true); + displayFeed.run(); + } + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to open collaboration contact list", e); + } + return event; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CopyTextAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CopyTextAction.java new file mode 100644 index 0000000000..41897cbc75 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CopyTextAction.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * Copies the text out of a styled text widget + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 17, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CopyTextAction extends Action { + private StyledText text; + + public CopyTextAction(StyledText text) { + this.text = text; + setText("Copy"); + } + + @Override + public void run() { + text.copy(); + } + + @Override + public ImageDescriptor getImageDescriptor() { + return PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_TOOL_COPY); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CreateGroupAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CreateGroupAction.java new file mode 100644 index 0000000000..bcbe35b6dc --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CreateGroupAction.java @@ -0,0 +1,80 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CreateGroupDialog; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Create a new local group, if the action is given users they will be added to + * the new group. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class CreateGroupAction extends Action { + + private final IUser[] users; + + public CreateGroupAction() { + super("Create Group", IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "add_group.gif")); + this.users = new IUser[0]; + setEnabled(CollaborationConnection.getConnection() != null); + } + + public CreateGroupAction(IUser... users) { + super("New Group...", IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "add_group.gif")); + this.users = users; + } + + @Override + public void run() { + CreateGroupDialog dialog = new CreateGroupDialog(Display.getCurrent() + .getActiveShell()); + dialog.open(); + String group = dialog.getNewGroup(); + if (group == null) { + return; + } + for (IUser user : users) { + CollaborationConnection.getConnection().getContactsManager() + .addToLocalGroup(group, user); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CreateSessionAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CreateSessionAction.java new file mode 100644 index 0000000000..d76fa8dc9b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CreateSessionAction.java @@ -0,0 +1,140 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CreateSessionData; +import com.raytheon.uf.viz.collaboration.ui.CreateSessionDialog; +import com.raytheon.uf.viz.collaboration.ui.IUserSelector; +import com.raytheon.uf.viz.collaboration.ui.session.CollaborationSessionView; +import com.raytheon.uf.viz.collaboration.ui.session.SessionView; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Create a new session, if users are provided they will be invited to the + * session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class CreateSessionAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CreateSessionAction.class); + + private IUserSelector userSelection; + + public CreateSessionAction() { + this(null); + } + + public CreateSessionAction(IUserSelector userSelection) { + super("Create Session...", getCreateSessionImageDescriptor()); + this.userSelection = userSelection; + } + + @Override + public void run() { + CollaborationConnection sessionManager = CollaborationConnection + .getConnection(); + if (sessionManager == null) { + return; + } + + CreateSessionDialog dialog = new CreateSessionDialog(Display + .getCurrent().getActiveShell()); + dialog.open(); + + CreateSessionData result = (CreateSessionData) dialog.getReturnValue(); + if (result != null) { + String sessionId = result.getSessionId(); + if (result.isCollaborationSession()) { + try { + CaveWorkbenchPageManager.getActiveInstance().showView( + CollaborationSessionView.ID, sessionId, + IWorkbenchPage.VIEW_ACTIVATE); + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to open collaboration sesson", e); + } + } else { + try { + CaveWorkbenchPageManager.getActiveInstance().showView( + SessionView.ID, sessionId, + IWorkbenchPage.VIEW_ACTIVATE); + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to open text only chat session", e); + } catch (Exception e) { + statusHandler.handle(Priority.ERROR, + "Unable to open chat room view", e); + } + } + + try { + if (result.isInviteUsers() && userSelection != null) { + IUser[] users = userSelection.getSelectedUsers(); + + if (users.length > 0) { + InviteAction invite = new InviteAction( + (IVenueSession) CollaborationConnection + .getConnection().getSession(sessionId), + users); + invite.setInviteMessage(result.getInviteMessage()); + invite.run(); + } + } + } catch (Exception e) { + statusHandler.handle(Priority.ERROR, + "Error sending invitation", e); + } + } + } + + public static ImageDescriptor getCreateSessionImageDescriptor() { + return IconUtil.getImageDescriptor(Activator.getDefault().getBundle(), + "add_collaborate.gif"); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CutTextAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CutTextAction.java new file mode 100644 index 0000000000..ab6dfc7dc0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/CutTextAction.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * Cuts text out of a styled text widget + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 17, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CutTextAction extends Action { + private StyledText text; + + public CutTextAction(StyledText text) { + this.text = text; + setText("Cut"); + } + + @Override + public void run() { + text.cut(); + } + + @Override + public ImageDescriptor getImageDescriptor() { + return PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_TOOL_CUT); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/DeleteGroupAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/DeleteGroupAction.java new file mode 100644 index 0000000000..a93c2129ca --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/DeleteGroupAction.java @@ -0,0 +1,60 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Delete a local group + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class DeleteGroupAction extends Action { + + private final String group; + + public DeleteGroupAction(String group) { + super("Delete " + group, IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "remove_group.gif")); + this.group = group; + } + + @Override + public void run() { + CollaborationConnection.getConnection().getContactsManager() + .deleteLocalGroup(group); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/DisplayFeedAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/DisplayFeedAction.java new file mode 100644 index 0000000000..283887e690 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/DisplayFeedAction.java @@ -0,0 +1,198 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.SWT; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.session.SessionFeedView; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Display the feed view + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class DisplayFeedAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(DisplayFeedAction.class); + + // TODO make this configurable? + public static final String FEED_VENUE = "nws-collaboration"; + + public DisplayFeedAction() { + super("Display Feed", SWT.TOGGLE); + setImageDescriptor(IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "feed.gif")); + setEnabled(CollaborationConnection.getConnection() != null); + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + page.addPartListener(new PartListener(this)); + if (isEnabled()) { + String sessionId = getSessionId(false); + if (sessionId != null) { + IViewReference ref = page.findViewReference(SessionFeedView.ID, + sessionId); + setChecked(ref != null); + } + } + } + + private static String getSessionId(boolean create) { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + String sessionId = null; + for (ISession session : connection.getSessions()) { + if (session instanceof IVenueSession) { + if (((IVenueSession) session).getVenue().getInfo() + .getVenueName().startsWith(FEED_VENUE)) { + sessionId = session.getSessionId(); + } + } + } + if (sessionId == null && create) { + try { + IVenueSession session = connection + .joinTextOnlyVenue(FEED_VENUE); + sessionId = session.getSessionId(); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to join the collaboration feed", e); + } + } + return sessionId; + } + + @Override + public void run() { + // handle if it is clicked to close or open the view as + // necessary + CaveWorkbenchPageManager page = CaveWorkbenchPageManager + .getActiveInstance(); + String sessionId = getSessionId(isChecked()); + if (!isChecked()) { + IViewReference ref = page.findViewReference(SessionFeedView.ID, + sessionId); + if (ref != null) { + page.hideView(ref); + } + } else { + try { + page.showView(SessionFeedView.ID, sessionId, + IWorkbenchPage.VIEW_ACTIVATE); + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to join collaboration feed", e); + } + } + } + + private static class PartListener implements IPartListener { + + private final Reference actionRef; + + public PartListener(DisplayFeedAction action) { + actionRef = new WeakReference(action); + } + + private void clean(IWorkbenchPart part) { + if (actionRef.get() == null) { + part.getSite().getPage().removePartListener(this); + } + } + + private void setChecked(boolean checked) { + Action action = actionRef.get(); + if (action != null) { + action.setChecked(checked); + } + } + + @Override + public void partActivated(IWorkbenchPart part) { + clean(part); + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + clean(part); + } + + @Override + public void partClosed(IWorkbenchPart part) { + clean(part); + if (part instanceof SessionFeedView) { + SessionFeedView view = (SessionFeedView) part; + if (view.getRoom().equals(getSessionId(false))) { + setChecked(false); + } + } + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + clean(part); + } + + @Override + public void partOpened(IWorkbenchPart part) { + clean(part); + if (part instanceof SessionFeedView) { + SessionFeedView view = (SessionFeedView) part; + if (view.getRoom().equals(getSessionId(false))) { + setChecked(true); + } + } + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/InviteAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/InviteAction.java new file mode 100644 index 0000000000..0c40a914a3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/InviteAction.java @@ -0,0 +1,231 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.SharedDisplayVenueInvite; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; + +/** + * Invire some users to join a session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class InviteAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(InviteAction.class); + + private final IUser[] users; + + private final IVenueSession session; + + private String inviteMessage; + + public InviteAction(IUser... users) { + super("Invite..."); + this.users = users; + this.session = null; + this.setToolTipText("Invite selected user(s) to join a session."); + // set the initial enabled state. + updateEnabled(); + setMenuCreator(new MenuCreator()); + } + + public InviteAction(IVenueSession session, IUser... users) { + super(session.getVenue().getInfo().getVenueDescription()); + this.users = users; + this.session = session; + this.setToolTipText("Invite selected user(s) to join a session."); + // set the initial enabled state. + isEnabled(); + } + + @Override + public void run() { + try { + VenueInvite invite = null; + if (session instanceof ISharedDisplaySession) { + SharedDisplayVenueInvite displayInvite = new SharedDisplayVenueInvite(); + displayInvite.setDataProvider(SharedDisplaySessionMgr + .getSessionContainer(session.getSessionId()) + .getSession().getCurrentDataProvider()); + displayInvite.setSessionLeader(SharedDisplaySessionMgr + .getSessionContainer(session.getSessionId()) + .getSession().getCurrentSessionLeader()); + invite = displayInvite; + } else { + invite = new VenueInvite(); + } + invite.setMessage(inviteMessage); + invite.setSessionId(session.getSessionId()); + invite.setSubject(session.getVenue().getInfo().getVenueSubject()); + List inviteList = new ArrayList(); + UserId inviter = CollaborationConnection.getConnection().getUser(); + for (IUser user : users) { + UserId userId = IDConverter.convertFrom(user); + + // don't invite the user sending the invite + if (!inviter.equals(userId)) { + inviteList.add(userId); + } + } + session.sendInvitation(inviteList, invite); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, "Error sending invitiation", + e); + } + } + + /** + * Set the enabled status of this action to be determined based off what + * users are available. + */ + public void updateEnabled() { + boolean enabled = false; + List newSessions = getNewSessions(); + if ((session == null && !newSessions.isEmpty()) + || newSessions.contains(session)) { + enabled = true; + } + setEnabled(enabled); + } + + private List getNewSessions() { + List result = new ArrayList(); + for (IUser user : users) { + for (IVenueSession session : getNewSessions(user)) { + if (!result.contains(session)) { + result.add(session); + } + } + } + return result; + } + + private List getNewSessions(IUser user) { + IPresence presence = CollaborationConnection.getConnection() + .getContactsManager().getPresence(user); + if (presence.getType() == Type.UNAVAILABLE) { + return Collections.emptyList(); + } + List result = new ArrayList(); + Collection sessions = CollaborationConnection.getConnection() + .getSessions(); + for (ISession session : sessions) { + if (session != null && session instanceof IVenueSession) { + final IVenueInfo info = ((IVenueSession) session).getVenue() + .getInfo(); + Collection participants = ((IVenueSession) session) + .getVenue().getParticipants(); + boolean notInRoom = true; + String id = user.getID().getName(); + for (UserId pa : participants) { + if (pa.isSameUser(id)) { + notInRoom = false; + break; + } + } + if (info != null && notInRoom) { + result.add((IVenueSession) session); + } + } + } + return result; + } + + private class MenuCreator implements IMenuCreator { + + private Menu menu; + + @Override + public void dispose() { + menu.dispose(); + } + + @Override + public Menu getMenu(Control parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + @Override + public Menu getMenu(Menu parent) { + menu = new Menu(parent); + fill(); + return menu; + } + + private void fill() { + for (IVenueSession session : getNewSessions()) { + Action action = new InviteAction(session, users); + IContributionItem contrib = new ActionContributionItem(action); + contrib.fill(menu, -1); + } + } + } + + /** + * @param inviteMessage + * the inviteMessage to set + */ + public void setInviteMessage(String inviteMessage) { + this.inviteMessage = inviteMessage; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LinkToEditorAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LinkToEditorAction.java new file mode 100644 index 0000000000..64708b1006 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LinkToEditorAction.java @@ -0,0 +1,180 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer; +import com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.session.CollaborationSessionView; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Link shared editors to their shared Sesion views. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class LinkToEditorAction extends Action { + + private static Map instanceMap = new HashMap(); + + private final IWorkbenchWindow window; + + private final String LINK_TO_EDITOR_PREF = "linktoeditor"; + + private PartListener partListener = new PartListener(); + + private LinkToEditorAction(IWorkbenchWindow window) { + super("Link Editor to Chat Session", Action.AS_CHECK_BOX); + setImageDescriptor(IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "link_to_editor.gif")); + // check the preference store on whether the user wants the preference + // checked or not + boolean checked = Activator.getDefault().getPreferenceStore() + .getBoolean(LINK_TO_EDITOR_PREF); + setChecked(checked); + this.window = window; + run(); + } + + @Override + public void run() { + boolean checked = isChecked(); + if (checked) { + window.getActivePage().addPartListener(partListener); + } else { + window.getActivePage().removePartListener(partListener); + } + Activator.getDefault().getPreferenceStore() + .setValue(LINK_TO_EDITOR_PREF, checked); + } + + public static synchronized LinkToEditorAction getInstance( + IWorkbenchWindow window) { + LinkToEditorAction instance = instanceMap.get(window); + if (instance == null) { + instance = new LinkToEditorAction(window); + instanceMap.put(window, instance); + } + instance.setEnabled(CollaborationConnection.getConnection() != null); + return instance; + } + + private static class PartListener implements IPartListener { + + @Override + public void partActivated(IWorkbenchPart part) { + if (part instanceof CollaborationSessionView) { + IWorkbenchPage page = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage(); + IRemoteDisplayContainer container = ((CollaborationSessionView) part) + .getDisplayContainer(); + if (container != null) { + IEditorPart editor = container.getActiveDisplayEditor(); + if (editor != null) { + page.bringToTop(editor); + } else if (container instanceof SharedEditorsManager) { + SharedEditorsManager sem = (SharedEditorsManager) container; + for (AbstractEditor sharedEditor : sem + .getSharedEditors()) { + page.bringToTop(sharedEditor); + break; + } + } + } + } else { + CaveWorkbenchPageManager page = CaveWorkbenchPageManager + .getActiveInstance(); + String sessionId = null; + if (part instanceof ICollaborationEditor) { + sessionId = ((ICollaborationEditor) part).getSessionId(); + } else if (part instanceof AbstractEditor) { + ISharedDisplaySession session = SharedEditorsManager + .getSharedEditorSession((AbstractEditor) part); + if (session != null) { + sessionId = session.getSessionId(); + } + } + if (sessionId != null) { + for (IViewReference ref : page.getViewReferences()) { + if (CollaborationSessionView.ID.equals(ref.getId())) { + CollaborationSessionView view = (CollaborationSessionView) ref + .getPart(false); + if (sessionId.equals(view.getSessionId())) { + page.bringToTop(view); + break; + } + } + } + } + } + } + + @Override + public void partBroughtToTop(IWorkbenchPart part) { + // Do nothing + } + + @Override + public void partClosed(IWorkbenchPart part) { + // Do nothing + } + + @Override + public void partDeactivated(IWorkbenchPart part) { + // Do nothing + } + + @Override + public void partOpened(IWorkbenchPart part) { + // Do nothing + } + + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LoginAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LoginAction.java new file mode 100644 index 0000000000..fc813adcb0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LoginAction.java @@ -0,0 +1,70 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.login.LoginDialog; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Open a dialog to log into collaboration. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 11, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class LoginAction extends Action { + + public LoginAction() { + super("Login...", IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "login.png")); + setEnabled(CollaborationConnection.getConnection() == null); + } + + @Override + public void run() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + Shell shell = Display.getDefault().getActiveShell(); + if (shell == null) { + return; + } + LoginDialog dlg = new LoginDialog(shell); + dlg.open(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LogoutAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LogoutAction.java new file mode 100644 index 0000000000..50a0056162 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/LogoutAction.java @@ -0,0 +1,115 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.io.IOException; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CollaborationGroupView; +import com.raytheon.uf.viz.collaboration.ui.ConnectionSubscriber; +import com.raytheon.uf.viz.collaboration.ui.editor.CollaborationEditor; +import com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Ask the user for confirmation, then logout. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 11, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class LogoutAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(LogoutAction.class); + + public LogoutAction() { + super("Logout", IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "logout.gif")); + setEnabled(CollaborationConnection.getConnection() != null); + } + + @Override + public void run() { + MessageBox messageBox = new MessageBox(Display.getCurrent() + .getActiveShell(), SWT.ICON_WARNING | SWT.OK | SWT.CANCEL); + messageBox.setText("Log Out of Collaboration"); + messageBox.setMessage("Logging out will sever your\n" + + "connection to the server and\n" + + "close all collaboration views\n" + "and editors."); + int result = messageBox.open(); + if (result == SWT.OK) { + for (IViewReference ref : CaveWorkbenchPageManager + .getActiveInstance().getViewReferences()) { + IViewPart view = ref.getView(false); + if (view instanceof AbstractSessionView + || view instanceof CollaborationGroupView) { + CaveWorkbenchPageManager.getActiveInstance().hideView(ref); + } + } + + // Close all Collaboration Editors. + for (IEditorReference ref : PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getActivePage() + .getEditorReferences()) { + IEditorPart editor = ref.getEditor(false); + if (editor instanceof CollaborationEditor) { + PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getActivePage().hideEditor(ref); + } + } + try { + Activator.getDefault().getPreferenceStore().save(); + } catch (IOException e) { + statusHandler.handle(Priority.WARN, + "Unable to save preferences", e); + } + CollaborationConnection connection = CollaborationConnection + .getConnection(); + ConnectionSubscriber.unsubscribe(connection); + connection.close(); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PasteTextAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PasteTextAction.java new file mode 100644 index 0000000000..b4b34ac742 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PasteTextAction.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.ui.ISharedImages; +import org.eclipse.ui.PlatformUI; + +/** + * Pastes the text into a styled text widget + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 17, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class PasteTextAction extends Action { + private StyledText text; + + public PasteTextAction(StyledText text) { + this.text = text; + setText("Paste"); + } + + @Override + public void run() { + text.paste(); + } + + @Override + public ImageDescriptor getImageDescriptor() { + return PlatformUI.getWorkbench().getSharedImages() + .getImageDescriptor(ISharedImages.IMG_TOOL_PASTE); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PeerToPeerChatAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PeerToPeerChatAction.java new file mode 100644 index 0000000000..4f0ae4ffbe --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PeerToPeerChatAction.java @@ -0,0 +1,127 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.session.PeerToPeerView; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Create a new chat session with a user + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class PeerToPeerChatAction extends Action { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(PeerToPeerChatAction.class); + + private final IUser user; + + public PeerToPeerChatAction(IUser user) { + super("Chat", IconUtil.getImageDescriptor(Activator.getDefault() + .getBundle(), "chats.gif")); + this.user = user; + updateEnabled(); + } + + @Override + public void run() { + IPresence presence = CollaborationConnection.getConnection() + .getContactsManager().getPresence(user); + if (presence.getType() != Type.UNAVAILABLE) { + UserId loginUserId = CollaborationConnection.getConnection() + .getUser(); + if (!loginUserId.equals(user)) { + createP2PChat(IWorkbenchPage.VIEW_ACTIVATE); + } + } + } + + /** + * Set the enabled status of this action to be determined based off what + * users are available. + */ + public void updateEnabled() { + boolean enabled = false; + IPresence presence = CollaborationConnection.getConnection() + .getContactsManager().getPresence(user); + if (presence.getType() != Type.UNAVAILABLE) { + UserId loginUserId = CollaborationConnection.getConnection() + .getUser(); + if (!loginUserId.getID().getName().equals(user.getID().getName())) { + enabled = true; + } + } + setEnabled(enabled); + } + + /** + * For creating a peer to peer chat, or adding to it. + * + * @param viewMode + * IWorkbenchPage.VIEW_CREATE or IWorkbenchPage.VIEW_ACTIVATE + * where create will not pop up the view in front of others and + * activate will. + * @return + */ + public PeerToPeerView createP2PChat(Integer viewMode) { + try { + String name = user.getID().getName(); + PeerToPeerView p2pView = (PeerToPeerView) CaveWorkbenchPageManager + .getActiveInstance().showView(PeerToPeerView.ID, name, + viewMode); + if (p2pView.getPeer() == null) { + p2pView.setPeer(IDConverter.convertFrom(user)); + } + return p2pView; + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, "Unable to open chat", e); + } + return null; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PopupNotifier.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PopupNotifier.java new file mode 100644 index 0000000000..66d3e63e9f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PopupNotifier.java @@ -0,0 +1,191 @@ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +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.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.core.VizApp; + +/** + * Notifications to show up in the bottom right of the monitor, will stack if + * another is currently displayed + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 26, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ +public class PopupNotifier { + + // how long the the popup is displayed + private static final int TIME_TO_DISPLAY = 4500; + + // what is currently popped up + private static List activeShells = new ArrayList(); + + private static Shell shell; + + private static Font titleFont = null; + + /** + * Creates and shows a notification dialog with a specific title and message + * + * For future could allow for different types of notifications to be + * different colors and different popup types? + * + * @param title + * @param message + */ + public static void notify(String title, String message) { + if (Display.getCurrent() == null + || Display.getCurrent().getActiveShell() == null) { + shell = new Shell(Display.getDefault(), SWT.NO_FOCUS | SWT.NO_TRIM + | SWT.ON_TOP); + GridLayout layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + shell.setLayout(layout); + shell.setForeground(Display.getDefault().getSystemColor( + SWT.COLOR_BLACK)); + shell.addListener(SWT.Dispose, new Listener() { + @Override + public void handleEvent(Event event) { + activeShells.remove(shell); + if (activeShells.isEmpty()) { + titleFont.dispose(); + } + } + }); + + final Composite comp = new Composite(shell, SWT.BORDER); + + layout = new GridLayout(1, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + comp.setLayout(layout); + comp.setLayoutData(data); + + CLabel titleLabel = new CLabel(comp, SWT.NONE); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.horizontalSpan = 2; + titleLabel.setLayoutData(data); + + // storing off the font, make the title font pop out a little more + // to the user + if (titleFont == null || titleFont.isDisposed()) { + titleFont = titleLabel.getFont(); + FontData fd = titleFont.getFontData()[0]; + fd.setStyle(SWT.BOLD); + fd.height = fd.height + 2; + titleFont = new Font(Display.getCurrent(), fd); + } + titleLabel.setFont(titleFont); + titleLabel.setText(title); + + // separate the title from the body text + Label separator = new Label(comp, SWT.HORIZONTAL | SWT.SEPARATOR); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + separator.setLayoutData(data); + separator.setVisible(true); + + // here is the text for the body of the message + Label text = new Label(comp, SWT.WRAP); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + text.setLayoutData(data); + text.setText(message); + + // maybe this should be minimum size? + shell.setSize(350, 100); + + // get the bottom right corner of the monitor + Rectangle clientArea = Display.getDefault().getMonitors()[0] + .getClientArea(); + + // and offset that may not be needed, only here to keep the box from + // touching the corner + int offset = 2; + int startX = clientArea.x + clientArea.width - shell.getSize().x + - offset; + int startY = clientArea.y + clientArea.height - shell.getSize().y + - offset; + + // move other shells up + synchronized (activeShells) { + if (!activeShells.isEmpty()) { + List modifiable = new ArrayList(activeShells); + Collections.reverse(modifiable); + for (Shell shell : modifiable) { + if (shell.isDisposed()) { + activeShells.remove(shell); + continue; + } + Point curLoc = shell.getLocation(); + shell.setLocation(curLoc.x, curLoc.y - 100); + if (curLoc.y - 100 < 0) { + activeShells.remove(shell); + shell.dispose(); + } + } + } + } + + shell.setLocation(startX, startY); + shell.setVisible(true); + + activeShells.add(shell); + startTimer(shell); + } + } + + /** + * @wbp.parser.entryPoint + */ + private static void startTimer(final Shell currShell) { + Timer timer = new Timer("Remove notification"); + TimerTask task = new TimerTask() { + + @Override + public void run() { + try { + if (currShell == null || currShell.isDisposed()) { + return; + } + VizApp.runAsync(new Runnable() { + public void run() { + currShell.dispose(); + }; + }); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + timer.schedule(task, TIME_TO_DISPLAY); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PrintLogActionContributionItem.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PrintLogActionContributionItem.java new file mode 100644 index 0000000000..d724c55357 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/PrintLogActionContributionItem.java @@ -0,0 +1,137 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.custom.StyledTextPrintOptions; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.printing.PrintDialog; +import org.eclipse.swt.printing.Printer; +import org.eclipse.swt.printing.PrinterData; + +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.session.IPrintableView; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * An ActionContributionItem to print a chat conversation log to + * printer. Utilizes StyledText's native print functionality. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public class PrintLogActionContributionItem extends ActionContributionItem { + + private static class PrintStyledTextAction extends Action { + + private IPrintableView view; + + private ModifyListener modListener; + + public PrintStyledTextAction(IPrintableView view) { + super("Print Log", IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "print.gif")); + this.view = view; + this.modListener = new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + setEnabled(shouldEnable()); + } + }; + this.view.getStyledText().addModifyListener(modListener); + setEnabled(shouldEnable()); + } + + private boolean shouldEnable() { + StyledText textControl = view.getStyledText(); + return ((textControl != null) && (!textControl.getText().isEmpty())); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + PrinterData data = new PrintDialog(view.getSite() + .getWorkbenchWindow().getShell()).open(); + if (data != null) { + Printer printer = new Printer(data); + StyledTextPrintOptions options = new StyledTextPrintOptions(); + options.header = view.getHeaderText(); + options.footer = "\t" + StyledTextPrintOptions.PAGE_TAG; + options.printTextFontStyle = true; + options.printTextForeground = true; + Runnable printJob = view.getStyledText() + .print(printer, options); + printJob.run(); + printer.dispose(); + } + } + + public void dispose() { + StyledText textControl = view.getStyledText(); + if ((textControl != null) && (!textControl.isDisposed())) { + textControl.removeModifyListener(modListener); + } + } + + } + + /** + * Constructor. + * + * @param view + * IPrintableView that will be used for printing. + * Ensure that view.getStyleText is not null or this + * will throw exceptions. + */ + public PrintLogActionContributionItem(IPrintableView view) { + super(new PrintStyledTextAction(view)); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.ActionContributionItem#dispose() + */ + @Override + public void dispose() { + ((PrintStyledTextAction) getAction()).dispose(); + super.dispose(); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/RemoveFromGroupAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/RemoveFromGroupAction.java new file mode 100644 index 0000000000..04579a715e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/RemoveFromGroupAction.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.action.Action; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.core.icon.IconUtil; + +/** + * Remove a user from a Local Group + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 3, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class RemoveFromGroupAction extends Action { + + private final IUser[] users; + + private final String group; + + public RemoveFromGroupAction(String group, IUser... users) { + super("Remove From " + group, IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "remove_group.gif")); + this.users = users; + this.group = group; + } + + @Override + public void run() { + ContactsManager manager = CollaborationConnection.getConnection() + .getContactsManager(); + for (IUser user : users) { + manager.deleteFromLocalGroup(group, user); + } + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ShareEditorAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ShareEditorAction.java new file mode 100644 index 0000000000..01a1f3b88d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ShareEditorAction.java @@ -0,0 +1,193 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.action.IMenuCreator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Menu; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.display.data.SessionContainer; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.actions.ContributedEditorMenuAction; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Action to share an editor with a chosen session + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 21, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class ShareEditorAction extends ContributedEditorMenuAction implements + IMenuCreator { + + private Menu menu; + + public ShareEditorAction() { + super("Share with", IAction.AS_DROP_DOWN_MENU); + } + + @Override + public boolean shouldBeVisible() { + return getActiveSharableEditor() != null && getSessions().size() > 0; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.IMenuCreator#dispose() + */ + @Override + public void dispose() { + if (menu != null) { + menu.dispose(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets + * .Control) + */ + @Override + public Menu getMenu(Control parent) { + if (menu != null) { + menu.dispose(); + } + + menu = new Menu(parent); + + fillMenu(menu); + return menu; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets + * .Menu) + */ + @Override + public Menu getMenu(Menu parent) { + if (menu != null) { + menu.dispose(); + } + + menu = new Menu(parent); + + fillMenu(menu); + + return menu; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#getMenuCreator() + */ + @Override + public IMenuCreator getMenuCreator() { + return this; + } + + /** + * @param menu2 + */ + private void fillMenu(Menu menu) { + final AbstractEditor editor = getActiveSharableEditor(); + if (editor != null) { + List sessions = getSessions(); + for (final ISharedDisplaySession session : sessions) { + IVenueInfo sessionInfo = session.getVenue().getInfo(); + ActionContributionItem aci = new ActionContributionItem( + new Action(sessionInfo.getVenueDescription()) { + @Override + public void run() { + try { + SharedEditorsManager.getManager(session) + .shareEditor(editor); + } catch (CollaborationException e) { + Activator.statusHandler.handle( + Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + }); + aci.fill(menu, -1); + } + } + } + + private AbstractEditor getActiveSharableEditor() { + AbstractEditor editor = EditorUtil + .getActiveEditorAs(AbstractEditor.class); + if (editor != null + && SharedEditorsManager.isBeingShared(editor) == false) { + return editor; + } + return null; + } + + private List getSessions() { + Collection sessionIds = SharedDisplaySessionMgr + .getActiveSessionIds(); + List sessions = new ArrayList(); + for (String sessionId : sessionIds) { + SessionContainer container = SharedDisplaySessionMgr + .getSessionContainer(sessionId); + if (container != null) { + ISharedDisplaySession session = container.getSession(); + if (session != null + && session.getUserID() == session + .getCurrentDataProvider()) { + sessions.add(container.getSession()); + } + } + } + return sessions; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ShowVenueAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ShowVenueAction.java new file mode 100644 index 0000000000..65f7a70c6d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/ShowVenueAction.java @@ -0,0 +1,65 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.ui.IViewReference; + +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * Bring a view for the given venue to the front of the display. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class ShowVenueAction extends Action { + + private final IVenueSession session; + + public ShowVenueAction(IVenueSession session) { + super("Open Session"); + this.session = session; + } + + @Override + public void run() { + for (IViewReference ref : CaveWorkbenchPageManager.getActiveInstance() + .getViewReferences()) { + if (session.getSessionId().equals(ref.getSecondaryId())) { + CaveWorkbenchPageManager.getActiveInstance().activate( + ref.getView(true)); + } + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/UnshareEditorAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/UnshareEditorAction.java new file mode 100644 index 0000000000..5da303d8da --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/UnshareEditorAction.java @@ -0,0 +1,91 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.viz.ui.EditorUtil; +import com.raytheon.viz.ui.actions.ContributedEditorMenuAction; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Action to remove an editor from being shared + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 11, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class UnshareEditorAction extends ContributedEditorMenuAction { + + public UnshareEditorAction() { + super("Unshare"); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + AbstractEditor editor = EditorUtil + .getActiveEditorAs(AbstractEditor.class); + SharedEditorsManager manager = getActiveSharedEditorManager(editor); + if (manager != null) { + try { + manager.removeEditor(editor); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + @Override + public boolean shouldBeVisible() { + AbstractEditor editor = EditorUtil + .getActiveEditorAs(AbstractEditor.class); + return getActiveSharedEditorManager(editor) != null; + } + + private SharedEditorsManager getActiveSharedEditorManager( + AbstractEditor editor) { + SharedEditorsManager manager = null; + ISharedDisplaySession session = SharedEditorsManager + .getSharedEditorSession(editor); + if (session != null) { + manager = SharedEditorsManager.getManager(session); + } + return manager; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/UserSearchAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/UserSearchAction.java new file mode 100644 index 0000000000..230a239e46 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/actions/UserSearchAction.java @@ -0,0 +1,56 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.actions; + +import org.eclipse.jface.action.Action; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.UserSearchDialog; + +/** + * Open the User Search Dialog + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class UserSearchAction extends Action { + + public UserSearchAction() { + super("User Search..."); + setEnabled(CollaborationConnection.getConnection() != null); + } + + public void run() { + new UserSearchDialog(Display.getCurrent().getActiveShell()).open(); + }; + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/AlertWord.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/AlertWord.java new file mode 100644 index 0000000000..9b4d61b17c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/AlertWord.java @@ -0,0 +1,164 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.data; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 16, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class AlertWord { + @DynamicSerializeElement + private String text; + + @DynamicSerializeElement + private Integer red; + + @DynamicSerializeElement + private Integer green; + + @DynamicSerializeElement + private Integer blue; + + @DynamicSerializeElement + private String soundPath; + + @DynamicSerializeElement + private String font; + + public AlertWord() { + + } + + public AlertWord(String text, RGB color) { + this.text = text; + red = color.red; + green = color.green; + blue = color.blue; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text + * the text to set + */ + public void setText(String text) { + this.text = text; + } + + /** + * @return the red + */ + public Integer getRed() { + return red; + } + + /** + * @param red + * the red to set + */ + public void setRed(Integer red) { + this.red = red; + } + + /** + * @return the green + */ + public Integer getGreen() { + return green; + } + + /** + * @param green + * the green to set + */ + public void setGreen(Integer green) { + this.green = green; + } + + /** + * @return the blue + */ + public Integer getBlue() { + return blue; + } + + /** + * @param blue + * the blue to set + */ + public void setBlue(Integer blue) { + this.blue = blue; + } + + /** + * @return the soundPath + */ + public String getSoundPath() { + return soundPath; + } + + /** + * @param soundPath + * the soundPath to set + */ + public void setSoundPath(String soundPath) { + this.soundPath = soundPath; + } + + /** + * @return the font + */ + public String getFont() { + return font; + } + + /** + * @param font + * the font to set + */ + public void setFont(String font) { + this.font = font; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/AlertWordWrapper.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/AlertWordWrapper.java new file mode 100644 index 0000000000..1d92f19611 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/AlertWordWrapper.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.data; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 16, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +@DynamicSerialize +public class AlertWordWrapper { + + @DynamicSerializeElement + private AlertWord[] alertWords; + + /** + * @return the alertWords + */ + public AlertWord[] getAlertWords() { + return alertWords; + } + + /** + * @param alertWords + * the alertWords to set + */ + public void setAlertWords(AlertWord[] alertWords) { + this.alertWords = alertWords; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/CollaborationGroupContainer.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/CollaborationGroupContainer.java new file mode 100644 index 0000000000..e8d1caad89 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/CollaborationGroupContainer.java @@ -0,0 +1,80 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.data; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.ecf.presence.roster.IRosterGroup; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.LocalGroups.LocalGroup; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 23, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationGroupContainer { + + private SessionGroupContainer sessionGroup = new SessionGroupContainer(); + + public CollaborationGroupContainer() { + } + + public List getObjects() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + return Collections.emptyList(); + } + List result = new ArrayList(); + result.add(connection.getUser()); + result.add(sessionGroup); + for (Object obj : connection.getRosterManager().getRoster().getItems()) { + if (obj instanceof IRosterGroup) { + result.add(obj); + } + } + for (LocalGroup group : connection.getContactsManager() + .getLocalGroups()) { + result.add(group); + } + return result; + } + + public SessionGroupContainer getSessionGroup() { + return sessionGroup; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/CollaborationKeywords.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/CollaborationKeywords.java new file mode 100644 index 0000000000..6dbb69d87b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/CollaborationKeywords.java @@ -0,0 +1,65 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.data; + +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 7, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationKeywords { + @XmlElement(name = "keyword") + List keywords; + + /** + * @param keywords + * the keywords to set + */ + public void setKeywords(List keywords) { + this.keywords = keywords; + } + + /** + * @return the keywords + */ + public List getKeywords() { + return keywords; + } + + public static List parseKeywords() { + return null; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/SessionGroupContainer.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/SessionGroupContainer.java new file mode 100644 index 0000000000..05897fbcb4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/data/SessionGroupContainer.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.data; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 6, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class SessionGroupContainer { + + public List getObjects() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + return Collections.emptyList(); + } + Collection sessions = connection.getSessions(); + List result = new ArrayList(); + for (ISession session : sessions) { + if (session instanceof IVenueSession) { + if (((IVenueSession) session).getVenue().getInfo() + .isPersistent() == false) { + result.add(session); + } + } + } + return result; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/CollaborationEditor.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/CollaborationEditor.java new file mode 100644 index 0000000000..09b091a57c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/CollaborationEditor.java @@ -0,0 +1,484 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.editor; + +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.ISaveablePart2; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.EditorPart; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.editor.ActivateRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.CollaborationEditorInput; +import com.raytheon.uf.viz.collaboration.display.editor.CreateRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.DisposeRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor; +import com.raytheon.uf.viz.collaboration.display.editor.RemoteDisplayRequested; +import com.raytheon.uf.viz.collaboration.display.editor.ReprojectRemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.rsc.CollaborationResourceData; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ResourceCapabilityChanged; +import com.raytheon.uf.viz.collaboration.display.rsc.event.ResourcePropertiesChanged; +import com.raytheon.uf.viz.collaboration.display.rsc.event.SharedResource; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractResourceData; +import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; +import com.raytheon.viz.ui.input.InputManager; + +/** + * A collaboration editor that displays the display of an editor shared by the + * Data Provider. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class CollaborationEditor extends EditorPart implements + ICollaborationEditor, ISaveablePart2 { + + private static final int NO_ACTIVE_DISPLAY = -1; + + private ISharedDisplaySession session; + + private CollaborationPaneManager paneManager; + + private Map displayMap = new LinkedHashMap( + 5, 1.25f, true); + + private int currentActiveDisplay = NO_ACTIVE_DISPLAY; + + private Set listeners = new LinkedHashSet(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.EditorPart#init(org.eclipse.ui.IEditorSite, + * org.eclipse.ui.IEditorInput) + */ + @Override + public void init(IEditorSite site, IEditorInput input) + throws PartInitException { + setInput(input); + setSite(site); + CollaborationEditorInput cei = (CollaborationEditorInput) input; + setPartName(cei.getName()); + session = SharedDisplaySessionMgr.getSessionContainer( + cei.getSessionId()).getSession(); + session.registerEventHandler(this); + paneManager = new CollaborationPaneManager(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets + * .Composite) + */ + @Override + public void createPartControl(Composite parent) { + paneManager.initializeComponents(paneManager, parent); + + RemoteDisplayRequested request = new RemoteDisplayRequested(); + request.setDisplayId(NO_ACTIVE_DISPLAY); + request.setUserId(session.getUserID().getFQName()); + try { + session.sendObjectToPeer(session.getCurrentDataProvider(), request); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#dispose() + */ + @Override + public void dispose() { + super.dispose(); + session.unregisterEventHandler(this); + } + + @Subscribe + public void createRemoteDisplay(CreateRemoteDisplay event) { + int displayId = event.getDisplayId(); + IRenderableDisplay display = displayMap.get(displayId); + if (display == null) { + display = event.getDisplay(); + for (ResourcePair rp : display.getDescriptor().getResourceList()) { + rp.getProperties().setSystemResource(true); + } + CollaborationResourceData crd = new CollaborationResourceData(this, + session, displayId); + ResourcePair rp = ResourcePair.constructSystemResourcePair(crd); + display.getDescriptor().getResourceList().add(rp); + display.getDescriptor().getResourceList() + .instantiateResources(display.getDescriptor(), true); + displayMap.put(displayId, display); + + fireListeners(displayId, display, RemoteDisplayChangeType.CREATED); + if (currentActiveDisplay == displayId) { + ActivateRemoteDisplay activate = new ActivateRemoteDisplay(); + activate.setDisplayId(displayId); + activateRemoteDisplay(activate); + } + } + } + + @Subscribe + public void activateRemoteDisplay(ActivateRemoteDisplay event) { + currentActiveDisplay = event.getDisplayId(); + final IRenderableDisplay display = displayMap.get(currentActiveDisplay); + if (currentActiveDisplay < 0) { + fireListeners(currentActiveDisplay, display, + RemoteDisplayChangeType.ACTIVATED); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + paneManager.deactivateDisplays(); + } + }); + } else if (display == null) { + RemoteDisplayRequested request = new RemoteDisplayRequested(); + request.setDisplayId(currentActiveDisplay); + request.setUserId(session.getUserID().getFQName()); + try { + session.sendObjectToPeer(session.getCurrentDataProvider(), + request); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } else { + fireListeners(currentActiveDisplay, display, + RemoteDisplayChangeType.ACTIVATED); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + paneManager.activateDisplay(currentActiveDisplay, display); + } + }); + } + } + + @Subscribe + public void disposeRemoteDisplay(DisposeRemoteDisplay event) { + final int displayId = event.getDisplayId(); + final IRenderableDisplay display = displayMap.remove(displayId); + if (display != null) { + fireListeners(event.getDisplayId(), display, + RemoteDisplayChangeType.DISPOSED); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + paneManager.dispose(display); + if (currentActiveDisplay == displayId) { + currentActiveDisplay = NO_ACTIVE_DISPLAY; + } + } + }); + } + } + + @Subscribe + public void reprojectRemoteDisplay(ReprojectRemoteDisplay event) { + IRenderableDisplay display = displayMap.get(event.getDisplayId()); + if (display != null) { + IDescriptor descriptor = display.getDescriptor(); + try { + descriptor.setGridGeometry(event.getTargetGeometry()); + Rectangle bounds = paneManager.getCanvasSize(display); + if (bounds != null) { + display.scaleToClientArea(bounds); + display.refresh(); + } + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + @Subscribe + public void sharedResourceEvent(SharedResource event) { + IRenderableDisplay display = displayMap.get(event.getDisplayId()); + if (display != null) { + IDescriptor descriptor = display.getDescriptor(); + event.getResource().getProperties().setSystemResource(true); + if (event.isRemoveResource()) { + descriptor.getResourceList().remove(event.getResource()); + } else { + descriptor.getResourceList().add(event.getResource()); + descriptor.getResourceList().instantiateResources(descriptor, + true); + } + } + } + + @Subscribe + public void sharedResourceCapabilityChanged(ResourceCapabilityChanged event) { + IRenderableDisplay display = displayMap.get(event.getDisplayId()); + if (display != null) { + AbstractResourceData lookFor = event.getResourceData(); + AbstractCapability capability = event.getCapability(); + for (ResourcePair rp : display.getDescriptor().getResourceList()) { + if (lookFor.equals(rp.getResourceData())) { + AbstractCapability rscCapability = capability.clone(); + rscCapability.setResourceData(rp.getResourceData()); + rp.getLoadProperties().getCapabilities() + .addCapability(rscCapability); + } + } + } + } + + @Subscribe + public void sharedResourcePropertiesChanged(ResourcePropertiesChanged event) { + IRenderableDisplay display = displayMap.get(event.getDisplayId()); + if (display != null) { + AbstractResourceData lookFor = event.getResourceData(); + ResourceProperties props = event.getProperties(); + props.setSystemResource(true); + for (ResourcePair rp : display.getDescriptor().getResourceList()) { + if (lookFor.equals(rp.getResourceData())) { + rp.setProperties(props); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor + * #setCanvasBounds(org.eclipse.swt.graphics.Rectangle) + */ + @Override + public void setCanvasBounds(int displayId, Rectangle canvasBounds) { + IRenderableDisplay display = displayMap.get(displayId); + if (display != null) { + paneManager.setCanvasSize(display, canvasBounds); + } + } + + public InputManager getInputManager() { + return paneManager.getMouseManager(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor + * #getSessionId() + */ + @Override + public String getSessionId() { + return session.getSessionId(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor + * #getActiveDisplayPane() + */ + @Override + public IDisplayPane getActiveDisplayPane() { + return paneManager.getActiveDisplayPane(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.EditorPart#isDirty() + */ + @Override + public boolean isDirty() { + return true; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.EditorPart#doSave(org.eclipse.core.runtime. + * IProgressMonitor) + */ + @Override + public void doSave(IProgressMonitor monitor) { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.EditorPart#doSaveAs() + */ + @Override + public void doSaveAs() { + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.EditorPart#isSaveAsAllowed() + */ + @Override + public boolean isSaveAsAllowed() { + return false; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + paneManager.setFocus(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.ISaveablePart2#promptToSaveOnClose() + */ + @Override + public int promptToSaveOnClose() { + // Let the user know why we refuse to close the editor + MessageDialog.openError(getSite().getShell(), "Closing Disabled", + "Please close the \"" + getPartName() + + "\" chat to exit the session."); + // Cancel the clsoe + return ISaveablePart2.CANCEL; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * addRemoteDisplayChangedListener + * (com.raytheon.uf.viz.collaboration.display. + * IRemoteDisplayContainer.IRemoteDisplayChangedListener) + */ + @Override + public void addRemoteDisplayChangedListener( + IRemoteDisplayChangedListener listener) { + listeners.add(listener); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * removeRemoteDisplayChangedListener + * (com.raytheon.uf.viz.collaboration.display + * .IRemoteDisplayContainer.IRemoteDisplayChangedListener) + */ + @Override + public void removeRemoteDisplayChangedListener( + IRemoteDisplayChangedListener listener) { + listeners.remove(listener); + } + + private void fireListeners(int displayId, IRenderableDisplay display, + RemoteDisplayChangeType changeType) { + RemoteDisplay rd = null; + if (display != null) { + rd = new RemoteDisplay(displayId, display); + } + for (IRemoteDisplayChangedListener listener : listeners) { + listener.remoteDisplayChanged(rd, changeType); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * getActiveDisplay() + */ + @Override + public RemoteDisplay getActiveDisplay() { + IRenderableDisplay display = displayMap.get(currentActiveDisplay); + if (display == null) { + return null; + } + return new RemoteDisplay(currentActiveDisplay, display); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * getActiveDisplayEditor() + */ + @Override + public IEditorPart getActiveDisplayEditor() { + return this; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer# + * disposeContainer() + */ + @Override + public void disposeContainer() { + getSite().getPage().closeEditor(this, false); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/CollaborationPaneManager.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/CollaborationPaneManager.java new file mode 100644 index 0000000000..c2abbc8a8e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/CollaborationPaneManager.java @@ -0,0 +1,277 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.editor; + +import java.util.IdentityHashMap; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.ScrollBar; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.datastructure.LoopProperties; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.viz.ui.panes.PaneManager; +import com.raytheon.viz.ui.panes.VizDisplayPane; + +/** + * PaneManager for the CollaborationEditor + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 7, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CollaborationPaneManager extends PaneManager { + + private static class DisplayData { + + private IDisplayPane pane; + + private Composite wrapperComp; + + private Composite canvasComp; + + private ScrolledComposite scrollable; + + private Rectangle scrollableBounds; + + private Rectangle canvasBounds; + + } + + private Map displayMap = new IdentityHashMap(); + + private DisplayData activeData; + + private LoopProperties loopProperties = new LoopProperties(); + + private Label noDisplayLabel; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.panes.PaneManager#initializeComponents(com.raytheon + * .uf.viz.core.IDisplayPaneContainer, org.eclipse.swt.widgets.Composite) + */ + @Override + public void initializeComponents(IDisplayPaneContainer container, + Composite comp) { + super.initializeComponents(container, comp); + GridLayout gl = new GridLayout(1, true); + gl.marginHeight = 0; + gl.marginWidth = 0; + comp.setLayout(gl); + noDisplayLabel = new Label(comp, SWT.NONE); + noDisplayLabel + .setText("The session leader is not viewing a shared display."); + noDisplayLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, + true)); + composite.layout(); + } + + public IDisplayPane activateDisplay(int displayId, + final IRenderableDisplay renderableDisplay) { + DisplayData data = displayMap.get(renderableDisplay); + if (data == null) { + data = new DisplayData(); + final DisplayData finalData = data; + // // scrollable composite + data.scrollable = new ScrolledComposite(composite, SWT.H_SCROLL + | SWT.V_SCROLL); + data.scrollable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, + true, true)); + + // Composite for canvas comp + data.wrapperComp = new Composite(data.scrollable, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + // Sets background color of wrapper composite to white + data.wrapperComp.setBackground(data.wrapperComp.getDisplay() + .getSystemColor(SWT.COLOR_WHITE)); + data.wrapperComp.setSize(1, 1); + + data.canvasComp = new Composite(data.wrapperComp, SWT.NONE); + data.canvasComp.setLayout(gl); + data.canvasComp.setSize(1, 1); + + // Set canvasComp as content on scrollable + data.scrollable.setContent(data.wrapperComp); + data.scrollable.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(Event event) { + finalData.scrollableBounds = ((Composite) event.widget) + .getBounds(); + setCanvasSize(renderableDisplay, finalData.canvasBounds); + } + }); + + try { + data.pane = createNewPane(renderableDisplay, data.canvasComp); + registerHandlers(data.pane); + data.canvasComp.layout(); + data.scrollableBounds = data.scrollable.getBounds(); + data.canvasBounds = data.canvasComp.getBounds(); + displayMap.put(renderableDisplay, data); + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + return null; + } + } + + if (activeData != null) { + setExclude(activeData, true); + } else { + noDisplayLabel.setVisible(false); + ((GridData) noDisplayLabel.getLayoutData()).exclude = true; + } + setExclude(data, false); + activeData = data; + composite.layout(); + activatedPane = currentMouseHoverPane = activeData.pane; + displayPanes.clear(); + displayPanes.add((VizDisplayPane) activatedPane); + return activeData.pane; + } + + public void deactivateDisplays() { + if (activeData != null) { + setExclude(activeData, true); + activeData = null; + } + noDisplayLabel.setVisible(true); + ((GridData) noDisplayLabel.getLayoutData()).exclude = false; + composite.layout(); + } + + protected void adjustPaneLayout(int paneCount) { + ;// don't do anything, we always want one pane displayed. + } + + /** + * @param display + */ + public void dispose(IRenderableDisplay display) { + DisplayData data = displayMap.remove(display); + if (data != null) { + data.pane.dispose(); + data.scrollable.dispose(); + if (activeData == data) { + activeData = null; + activatedPane = null; + displayPanes.clear(); + deactivateDisplays(); + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.panes.PaneManager#getLoopProperties() + */ + @Override + public LoopProperties getLoopProperties() { + return loopProperties; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.panes.PaneManager#setLoopProperties(com.raytheon. + * uf.viz.core.datastructure.LoopProperties) + */ + @Override + public void setLoopProperties(LoopProperties loopProperties) { + this.loopProperties = loopProperties; + } + + public Rectangle getCanvasSize(IRenderableDisplay display) { + Rectangle bounds = null; + DisplayData data = displayMap.get(display); + if (data != null) { + bounds = data.canvasBounds; + } + return bounds; + } + + public void setCanvasSize(IRenderableDisplay display, Rectangle bounds) { + DisplayData data = displayMap.get(display); + if (data == null) { + return; + } + data.canvasBounds = bounds; + data.canvasComp.setSize(bounds.width, bounds.height); + + Rectangle scrollableBounds = new Rectangle(data.scrollableBounds.x, + data.scrollableBounds.y, data.scrollableBounds.width, + data.scrollableBounds.height); + + // Subtract size of scroll bars if visible + ScrollBar vertical = data.scrollable.getVerticalBar(); + ScrollBar horizon = data.scrollable.getHorizontalBar(); + if (scrollableBounds.width <= data.canvasBounds.width) { + scrollableBounds.height -= horizon.getSize().y; + } + if (scrollableBounds.height <= data.canvasBounds.height) { + scrollableBounds.width -= vertical.getSize().x; + } + + data.wrapperComp.setSize( + Math.max(data.canvasBounds.width, scrollableBounds.width), + Math.max(data.canvasBounds.height, scrollableBounds.height)); + data.canvasComp.setLocation( + Math.max(0, (scrollableBounds.width - bounds.width) / 2), + Math.max(0, (scrollableBounds.height - bounds.height) / 2)); + data.wrapperComp.layout(); + data.canvasComp.layout(); + } + + private void setExclude(DisplayData data, boolean exclude) { + GridData gd = (GridData) data.scrollable.getLayoutData(); + data.scrollable.setVisible(!exclude); + gd.exclude = exclude; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/event/EventForwardingInputHandler.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/event/EventForwardingInputHandler.java new file mode 100644 index 0000000000..a2c0703c1e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/event/EventForwardingInputHandler.java @@ -0,0 +1,221 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.editor.event; + +import org.eclipse.swt.widgets.Event; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.ui.editor.event.InputEvent.EventType; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.rsc.IInputHandler; + +/** + * An input handler that forwards events to the Data Provider. Intended for use + * by the Session Leader. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 20, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class EventForwardingInputHandler implements IInputHandler { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(EventForwardingInputHandler.class); + + private ISharedDisplaySession session; + + private IDisplayPane displayPane; + + public EventForwardingInputHandler(ISharedDisplaySession session, + IDisplayPane displayPane) { + this.session = session; + this.displayPane = displayPane; + } + + private void sendEvent(InputEvent event) { + try { + session.sendObjectToPeer(session.getCurrentDataProvider(), event); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, "Error sending input event", + e); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseDown(int, int, + * int) + */ + @Override + public boolean handleMouseDown(int x, int y, int mouseButton) { + double[] coords = displayPane.screenToGrid(x, y, 0); + InputEvent event = new InputEvent(EventType.MOUSE_DOWN, coords[0], + coords[1], mouseButton); + sendEvent(event); + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseDownMove(int, + * int, int) + */ + @Override + public boolean handleMouseDownMove(int x, int y, int mouseButton) { + double[] coords = displayPane.screenToGrid(x, y, 0); + InputEvent event = new InputEvent(EventType.MOUSE_DOWN_MOVE, coords[0], + coords[1], mouseButton); + sendEvent(event); + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseUp(int, int, + * int) + */ + @Override + public boolean handleMouseUp(int x, int y, int mouseButton) { + double[] coords = displayPane.screenToGrid(x, y, 0); + InputEvent event = new InputEvent(EventType.MOUSE_UP, coords[0], + coords[1], mouseButton); + sendEvent(event); + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseHover(int, + * int) + */ + @Override + public boolean handleMouseHover(int x, int y) { + // TODO doesn't do anything right now to reduce bandwidth + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseMove(int, int) + */ + @Override + public boolean handleMouseMove(int x, int y) { + // TODO doesn't do anything right now to reduce bandwidth + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleDoubleClick(int, + * int, int) + */ + @Override + public boolean handleDoubleClick(int x, int y, int button) { + // TODO doesn't do anything right now to reduce bandwidth + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseWheel(org.eclipse + * .swt.widgets.Event, int, int) + */ + @Override + public boolean handleMouseWheel(Event event, int x, int y) { + double[] coords = displayPane.screenToGrid(x, y, 0); + InputEvent mevent = new InputEvent(EventType.MOUSE_WHEEL, coords[0], + coords[1], event.count); + sendEvent(mevent); + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseExit(org.eclipse + * .swt.widgets.Event) + */ + @Override + public boolean handleMouseExit(Event event) { + // TODO doesn't do anything right now to reduce bandwidth + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.IInputHandler#handleMouseEnter(org.eclipse + * .swt.widgets.Event) + */ + @Override + public boolean handleMouseEnter(Event event) { + // TODO doesn't do anything right now to reduce bandwidth + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleKeyDown(int) + */ + @Override + public boolean handleKeyDown(int keyCode) { + InputEvent event = new InputEvent(EventType.KEY_DOWN, -1, -1, keyCode); + sendEvent(event); + return false; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.IInputHandler#handleKeyUp(int) + */ + @Override + public boolean handleKeyUp(int keyCode) { + InputEvent event = new InputEvent(EventType.KEY_UP, -1, -1, keyCode); + sendEvent(event); + return false; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/event/InputEvent.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/event/InputEvent.java new file mode 100644 index 0000000000..dd532cf46d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/editor/event/InputEvent.java @@ -0,0 +1,110 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.editor.event; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * An input event that holds necessary information to recreate the event on a + * different machine. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 27, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +@DynamicSerialize +public class InputEvent { + + public enum EventType { + MOUSE_DOWN, MOUSE_DOWN_MOVE, MOUSE_UP, MOUSE_HOVER, MOUSE_MOVE, DOUBLE_CLICK, MOUSE_WHEEL, KEY_UP, KEY_DOWN + } + + @DynamicSerializeElement + protected double x; + + @DynamicSerializeElement + protected double y; + + /** + * Associated metadata with an event. In the case of a button click, it is + * the button id. For a scroll wheel, it is the count. For a key press, it + * is the key code. + */ + @DynamicSerializeElement + protected int eventData; + + @DynamicSerializeElement + protected EventType type; + + public InputEvent() { + + } + + public InputEvent(EventType type, double x, double y, int eventData) { + this.type = type; + this.x = x; + this.y = y; + this.eventData = eventData; + } + + public double getX() { + return x; + } + + public void setX(double x) { + this.x = x; + } + + public double getY() { + return y; + } + + public void setY(double y) { + this.y = y; + } + + public EventType getType() { + return type; + } + + public void setType(EventType type) { + this.type = type; + } + + public int getEventData() { + return eventData; + } + + public void setEventData(int eventData) { + this.eventData = eventData; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/login/ChangeStatusDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/login/ChangeStatusDialog.java new file mode 100644 index 0000000000..b80d0b327f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/login/ChangeStatusDialog.java @@ -0,0 +1,183 @@ +package com.raytheon.uf.viz.collaboration.ui.login; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Change the user Mode Status and the optional message. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 3, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class ChangeStatusDialog extends CaveSWTDialog { + + private Label userLabel; + + private Text messageTF; + + public ChangeStatusDialog(Shell parentShell) { + super(parentShell, SWT.DIALOG_TRIM); + setText("Change Status Message"); + } + + private Control createDialogArea(Composite parent) { + GridData gd = null; + Composite body = new Composite(parent, SWT.NONE); + body.setLayout(new GridLayout(2, false)); + userLabel = new Label(body, SWT.NONE); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + userLabel.setLayoutData(gd); + userLabel.setText(""); + + Label label = new Label(body, SWT.NONE); + label.setText("Message: "); + + messageTF = new Text(body, SWT.BORDER | SWT.MULTI); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumWidth = 200; + messageTF.setLayoutData(gd); + + return body; + } + + @Override + protected void initializeComponents(Shell shell) { + shell.setLayout(new GridLayout(1, false)); + createDialogArea(shell); + createButtonBar(shell); + } + + private void createButtonBar(Composite parent) { + GridData gd = null; + Composite bar = new Composite(parent, SWT.NONE); + gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); + bar.setLayout(new GridLayout(0, true)); + bar.setLayoutData(gd); + createButton(bar, IDialogConstants.OK_ID, "Send", true); + + createButton(bar, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + @Override + protected void preOpened() { + super.preOpened(); + IPreferenceStore prefStore = Activator.getDefault() + .getPreferenceStore(); + userLabel.setText(prefStore.getString(CollabPrefConstants.P_USERNAME) + + "@" + prefStore.getString(CollabPrefConstants.P_SERVER)); + messageTF.setText(prefStore.getString(CollabPrefConstants.P_MESSAGE)); + messageTF.selectAll(); + } + + /** + * Creates a new button with the given id. + *

+ * The Dialog implementation of this framework method creates a + * standard push button, registers it for selection events including button + * presses, and registers default buttons with its shell. The button id is + * stored as the button's client data. If the button id is + * IDialogConstants.CANCEL_ID, the new button will be + * accessible from getCancelButton(). If the button id is + * IDialogConstants.OK_ID, the new button will be accesible + * from getOKButton(). Note that the parent's layout is assumed + * to be a GridLayout and the number of columns in this layout + * is incremented. Subclasses may override. + *

+ * + * @param parent + * the parent composite + * @param id + * the id of the button (see IDialogConstants.*_ID + * constants for standard dialog button ids) + * @param label + * the label from the button + * @param defaultButton + * true if the button is to be the default button, + * and false otherwise + * + * @return the new button + * + * @see #getCancelButton + * @see #getOKButton() + */ + protected Button createButton(Composite parent, int id, String label, + boolean defaultButton) { + // increment the number of columns in the button bar + ((GridLayout) parent.getLayout()).numColumns++; + Button button = new Button(parent, SWT.PUSH); + button.setText(label); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumWidth = 70; + button.setLayoutData(gd); + button.setData(new Integer(id)); + button.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent event) { + Integer val = (Integer) event.widget.getData(); + if (val != IDialogConstants.OK_ID) { + setReturnValue(null); + } else { + String modeMessage = messageTF.getText().trim(); + IPreferenceStore prefStore = Activator.getDefault() + .getPreferenceStore(); + prefStore.setValue(CollabPrefConstants.P_MESSAGE, + modeMessage); + } + ChangeStatusDialog.this.getShell().dispose(); + } + }); + if (defaultButton) { + Shell shell = parent.getShell(); + if (shell != null) { + shell.setDefaultButton(button); + } + } + return button; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/login/LoginDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/login/LoginDialog.java new file mode 100644 index 0000000000..625a1a4389 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/login/LoginDialog.java @@ -0,0 +1,386 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.login; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation.HostConfig; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation.SiteConfig; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnectionData; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CollaborationUtils; +import com.raytheon.uf.viz.collaboration.ui.ConnectionSubscriber; +import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; + +/** + * Login dialog + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class LoginDialog extends Dialog { + + private static final String SERVER_ENABLED = "OK"; + + private static final String SERVER_DISABLED = "Edit"; + + private IPreferenceStore preferences; + + private CollaborationConnectionData loginData; + + private Text userText; + + private Combo serverText; + + private Text passwordText; + + private Combo statusCombo; + + private Text messageText; + + private Map attributeCombos; + + private Button loginButton; + + private Button cancelButton; + + private Shell shell; + + /** + * @param parentShell + */ + public LoginDialog(Shell parentShell) { + super(parentShell, SWT.DIALOG_TRIM); + preferences = Activator.getDefault().getPreferenceStore(); + loginData = new CollaborationConnectionData(); + readLoginData(); + } + + public void open() { + shell = new Shell(getParent(), getStyle()); + shell.setText("Collaboration Server Login"); + shell.setLayout(new GridLayout(1, false)); + // shell.setLayout(new GridLayout(1, false)); + createMainDialogArea(shell); + createAttributesArea(shell); + createButtonsArea(shell); + shell.setDefaultButton(loginButton); + shell.pack(); + shell.setVisible(true); + shell.open(); + // block the UI. + Display display = getParent().getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + } + + /** + * @param shell + */ + private void createMainDialogArea(Composite parent) { + final Composite body = new Composite(parent, SWT.NONE); + body.setLayout(new GridLayout(3, false)); + + // Add user text + new Label(body, SWT.NONE).setText("User: "); + userText = new Text(body, SWT.BORDER); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + userText.setLayoutData(gd); + userText.setText(loginData.getUserName()); + + // Server setting + new Label(body, SWT.NONE).setText("Server: "); + serverText = new Combo(body, SWT.BORDER | SWT.READ_ONLY | SWT.DROP_DOWN); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumWidth = 200; + gd.horizontalSpan = 2; + serverText.setLayoutData(gd); + // retrieve the servers + SiteConfigInformation information = SiteConfigurationManager + .getSiteConfigInformation(); + if (information.getServer() == null + || information.getServer().size() == 0) { + String[] text = new String[1]; + text[0] = "Server not configured."; + serverText.setData("configured", false); + serverText.setItems(text); + serverText.setText(text[0]); + } else { + // put configured as true so we don't disable the login button + serverText.setData("configured", true); + List servers = information.getServer(); + String[] names = new String[servers.size()]; + int index = 0; + for (int i = 0; i < names.length; i++) { + names[i] = servers.get(i).getPrettyName() + " : " + + servers.get(i).getHostname(); + if (loginData.getServer().equals(names[i])) { + index = i; + } + } + serverText.setItems(names); + serverText.select(index); + } + + // Password setting + new Label(body, SWT.NONE).setText("Password: "); + passwordText = new Text(body, SWT.PASSWORD | SWT.BORDER); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + passwordText.setLayoutData(gd); + passwordText.setTextLimit(32); + + // Status setting + new Label(body, SWT.NONE).setText("Status: "); + statusCombo = new Combo(body, SWT.DEFAULT); + + // TODO get possible status options from config file? + for (IPresence.Mode mode : CollaborationUtils.statusModes) { + statusCombo.add(CollaborationUtils.formatMode(mode)); + } + String status = loginData.getStatus(); + if (status != null && status.isEmpty() == false) { + statusCombo.setText(status); + } else { + statusCombo.select(0); + } + // Empty filler label so the combo and label stay aligned + new Label(body, SWT.NONE); + + // Message setting + new Label(body, SWT.NONE).setText("Message: "); + messageText = new Text(body, SWT.BORDER); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + messageText.setLayoutData(gd); + messageText.setText(loginData.getMessage()); + + body.setTabList(new Control[] { userText, passwordText, messageText }); + } + + /** + * @param shell + */ + private void createAttributesArea(Composite parent) { + attributeCombos = new HashMap(); + Composite comp = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(4, false); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + layout.marginHeight = 0; + layout.marginWidth = 0; + comp.setLayout(layout); + comp.setLayoutData(gd); + + // TODO: Default to previous settings + SiteConfigInformation information = SiteConfigurationManager + .getSiteConfigInformation(); + List sites = new ArrayList(); + final Map roles = new HashMap(); + for (SiteConfig conf : information.getConfig()) { + sites.add(conf.getSite()); + roles.put(conf.getSite(), conf.getRoles()); + } + Label infoLabel = new Label(comp, SWT.NONE); + infoLabel.setText(SiteConfigInformation.SITE_NAME + ":"); + infoLabel + .setLayoutData(new GridData(SWT.NONE, SWT.CENTER, false, true)); + + final Combo siteCombo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY); + siteCombo.setData(SiteConfigInformation.SITE_NAME); + siteCombo.setItems(sites.toArray(new String[0])); + gd = new GridData(SWT.FILL, SWT.NONE, true, true); + siteCombo.setLayoutData(gd); + siteCombo.select(0); + attributeCombos.put(SiteConfigInformation.SITE_NAME, siteCombo); + + infoLabel = new Label(comp, SWT.NONE); + infoLabel.setText(SiteConfigInformation.ROLE_NAME + ":"); + infoLabel + .setLayoutData(new GridData(SWT.NONE, SWT.CENTER, false, true)); + + final Combo roleCombo = new Combo(comp, SWT.DROP_DOWN | SWT.READ_ONLY); + roleCombo.setData(SiteConfigInformation.ROLE_NAME); + roleCombo.setItems(roles.get(siteCombo.getItem(siteCombo + .getSelectionIndex()))); + gd = new GridData(SWT.FILL, SWT.NONE, true, true); + roleCombo.setLayoutData(gd); + roleCombo.select(0); + attributeCombos.put(SiteConfigInformation.ROLE_NAME, roleCombo); + + siteCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + roleCombo.setItems(roles.get(siteCombo.getItem(siteCombo + .getSelectionIndex()))); + roleCombo.select(0); + } + }); + } + + private void createButtonsArea(Composite parent) { + Composite bar = new Composite(parent, SWT.NONE); + bar.setLayout(new GridLayout(2, true)); + bar.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true, false)); + + GridData buttonData = new GridData(SWT.FILL, SWT.FILL, true, true); + buttonData.minimumWidth = 70; + + loginButton = new Button(bar, SWT.PUSH); + loginButton.setText("Login"); + if ((Boolean) serverText.getData("configured") == false) { + loginButton.setEnabled(false); + } + loginButton.setLayoutData(buttonData); + loginButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + loginData.setUserName(userText.getText().trim()); + loginData.setPassword(passwordText.getText().trim()); + loginData.setServer(serverText.getText().split(":")[1].trim()); + loginData.setStatus(statusCombo.getText()); + loginData.setMessage(messageText.getText().trim()); + Map attributes = new HashMap(); + for (String attribKey : attributeCombos.keySet()) { + Combo cbo = attributeCombos.get(attribKey); + attributes.put(attribKey, cbo.getText()); + } + loginData.setAttributes(attributes); + + // Validate everything is set properly + List errorMessages = new ArrayList(); + if (loginData.getUserName().isEmpty()) { + errorMessages.add("Must enter a user."); + } else { + loginData + .setUserName(loginData.getUserName().toLowerCase()); + } + + if (loginData.getServer().isEmpty()) { + errorMessages.add("Must have a server."); + } + + if (loginData.getPassword().isEmpty()) { + errorMessages.add("Must enter a password."); + } + + if (errorMessages.size() > 0) { + // Item(s) is not set properly + StringBuilder sb = new StringBuilder(); + String prefix = ""; + for (String msg : errorMessages) { + sb.append(prefix).append(msg); + prefix = "\n"; + } + MessageBox messageBox = new MessageBox(event.widget + .getDisplay().getActiveShell(), SWT.ERROR); + messageBox.setText("Login Error"); + messageBox.setMessage(sb.toString()); + messageBox.open(); + } else { + try { + CollaborationConnection connection = CollaborationConnection + .connect(loginData); + ConnectionSubscriber.subscribe(connection); + storeLoginData(); + shell.dispose(); + } catch (CollaborationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error connecting to collaboration server: " + + e.getLocalizedMessage(), e); + } + } + } + }); + + cancelButton = new Button(bar, SWT.PUSH); + cancelButton.setText("Cancel"); + cancelButton.setLayoutData(buttonData); + cancelButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + SiteConfigurationManager.nullifySiteConfigInstance(); + shell.dispose(); + } + }); + } + + private void storeLoginData() { + preferences.setValue(CollabPrefConstants.P_USERNAME, + loginData.getUserName()); + preferences.setValue(CollabPrefConstants.P_SERVER, + loginData.getServer()); + preferences.setValue(CollabPrefConstants.P_MESSAGE, + loginData.getMessage()); + preferences.setValue(CollabPrefConstants.P_STATUS, + loginData.getStatus()); + } + + private void readLoginData() { + loginData.setUserName(preferences + .getString(CollabPrefConstants.P_USERNAME)); + loginData + .setServer(preferences.getString(CollabPrefConstants.P_SERVER)); + loginData + .setStatus(preferences.getString(CollabPrefConstants.P_STATUS)); + loginData.setMessage(preferences + .getString(CollabPrefConstants.P_MESSAGE)); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollabPrefConstants.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollabPrefConstants.java new file mode 100644 index 0000000000..3219be8da9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollabPrefConstants.java @@ -0,0 +1,56 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.prefs; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 24, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class CollabPrefConstants { + + public static final String P_SERVER = "collaborationServer"; + + public static final String P_USERNAME = "username"; + + public static final String P_STATUS = "status"; + + public static final String P_MESSAGE = "message"; + + public static final String AUTO_JOIN = "autojoin"; + + public class HttpCollaborationConfiguration { + public static final String P_SESSION_CONFIGURED = "http.sessionConfigured"; + + public static final String P_HTTP_SESSION_URL = "http.sessionURL"; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollabPrefInitializer.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollabPrefInitializer.java new file mode 100644 index 0000000000..26f62bc3f2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollabPrefInitializer.java @@ -0,0 +1,69 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.prefs; + +import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer; +import org.eclipse.ecf.presence.IPresence.Mode; +import org.eclipse.jface.preference.IPreferenceStore; + +import com.raytheon.uf.viz.collaboration.ui.Activator; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 24, 2012            njensen     Initial creation
+ * 
+ * 
+ * + * @author njensen + * @version 1.0 + */ + +public class CollabPrefInitializer extends AbstractPreferenceInitializer { + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer# + * initializeDefaultPreferences() + */ + @Override + public void initializeDefaultPreferences() { + IPreferenceStore store = Activator.getDefault().getPreferenceStore(); + + store.setDefault(CollabPrefConstants.P_SERVER, ""); + store.setDefault(CollabPrefConstants.AUTO_JOIN, true); + + // TODO better default? + store.setDefault(CollabPrefConstants.P_USERNAME, + System.getProperty("user.name")); + + store.setDefault(CollabPrefConstants.P_STATUS, + Mode.AVAILABLE.toString()); + store.setDefault(CollabPrefConstants.P_MESSAGE, ""); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationAlertWordsPreferencePage.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationAlertWordsPreferencePage.java new file mode 100644 index 0000000000..6dfc3b6817 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationAlertWordsPreferencePage.java @@ -0,0 +1,283 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.prefs; + +import java.io.File; +import java.util.List; + +import org.eclipse.jface.preference.ColorFieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.jface.preference.FileFieldEditor; +import org.eclipse.jface.preference.StringFieldEditor; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.RGB; +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.Display; +import org.eclipse.swt.widgets.FontDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManager; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CollaborationUtils; +import com.raytheon.uf.viz.collaboration.ui.data.AlertWord; +import com.raytheon.uf.viz.collaboration.ui.data.AlertWordWrapper; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationAlertWordsPreferencePage extends + FieldEditorPreferencePage implements IWorkbenchPreferencePage { + + private TableViewer viewer = null; + + /** + * + */ + public CollaborationAlertWordsPreferencePage() { + super(GRID); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors + * () + */ + @Override + protected void createFieldEditors() { + + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.horizontalSpan = 3; + + viewer = new TableViewer(getFieldEditorParent()); + viewer.setContentProvider(new CollaborationPreferenceContentProvider()); + viewer.setLabelProvider(new CollaborationPreferencesLabelProvider()); + viewer.getTable().setLayoutData(data); + + final StringFieldEditor stringEditor = new StringFieldEditor( + "significantword", "Word", getFieldEditorParent()) { + @Override + protected void doLoad() { + super.doLoad(); + this.setStringValue(""); + } + }; + this.addField(stringEditor); + + final ColorFieldEditor colorEditor = new ColorFieldEditor( + "coloreditor", "Color", getFieldEditorParent()); + this.addField(colorEditor); + colorEditor.loadDefault(); + + Composite fontComp = new Composite(getFieldEditorParent(), SWT.NONE); + GridLayout layout = new GridLayout(3, false); + layout.marginHeight = 0; + layout.marginWidth = 0; + fontComp.setLayout(layout); + data = new GridData(SWT.FILL, SWT.NONE, true, false); + data.horizontalSpan = 3; + + fontComp.setLayoutData(data); + + Label fontName = new Label(fontComp, SWT.NONE); + fontName.setText("Font"); + data = new GridData(SWT.FILL, SWT.NONE, true, true); + fontName.setLayoutData(data); + + final Label fontLabel = new Label(fontComp, SWT.NONE); + fontLabel.setText(StringConverter.asString(Display.getCurrent() + .getSystemFont().getFontData()[0])); + data = new GridData(SWT.FILL, SWT.NONE, true, true); + fontLabel.setLayoutData(data); + + Button fontButton = new Button(fontComp, SWT.PUSH); + fontButton.setText("Change..."); + data = new GridData(SWT.FILL, SWT.NONE, true, true); + + final FileFieldEditor fileEditor = new FileFieldEditor("fileeditor", + "Sound File", getFieldEditorParent()); + + PathManager manager = (PathManager) PathManagerFactory.getPathManager(); + LocalizationContext context = manager.getContext( + LocalizationType.CAVE_STATIC, LocalizationLevel.USER); + LocalizationFile file = manager.getLocalizationFile(context, + "collaboration" + File.separator + "sounds" + File.separator); + if (!file.exists()) { + file.getFile().mkdirs(); + } + fileEditor.setFilterPath(file.getFile()); + this.addField(fileEditor); + + fontButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FontDialog dialog = new FontDialog(Display.getCurrent() + .getActiveShell()); + dialog.setFontList(StringConverter.asFontDataArray(fontLabel + .getText())); + FontData data = dialog.open(); + if (data != null) { + fontLabel.setText(StringConverter.asString(data)); + } + } + }); + data = new GridData(SWT.NONE, SWT.NONE, false, true); + fontButton.setLayoutData(data); + + Composite buttonComp = new Composite(getFieldEditorParent(), SWT.NONE); + buttonComp.setLayout(new GridLayout(3, false)); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + data.horizontalSpan = 3; + buttonComp.setLayoutData(data); + + Button saveButton = new Button(buttonComp, SWT.PUSH); + saveButton.setText("Save Current"); + saveButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (!stringEditor.getStringValue().isEmpty()) { + AlertWord word = new AlertWord(stringEditor + .getStringValue(), colorEditor.getColorSelector() + .getColorValue()); + word.setFont(fontLabel.getText()); + word.setSoundPath(fileEditor.getStringValue()); + int index = viewer.getTable().getSelectionIndex(); + if (index != -1) { + ((List) viewer.getInput()).set(index, word); + } else { + ((List) viewer.getInput()).add(word); + } + viewer.refresh(); + } + } + }); + data = new GridData(SWT.NONE, SWT.NONE, false, true); + saveButton.setLayoutData(data); + + Button addButton = new Button(buttonComp, SWT.PUSH); + addButton.setText("Add New"); + addButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (!stringEditor.getStringValue().isEmpty()) { + AlertWord word = new AlertWord(stringEditor + .getStringValue(), colorEditor.getColorSelector() + .getColorValue()); + word.setFont(fontLabel.getText()); + word.setSoundPath(fileEditor.getStringValue()); + ((List) viewer.getInput()).add(word); + viewer.refresh(); + } + } + }); + data = new GridData(SWT.NONE, SWT.NONE, false, true); + addButton.setLayoutData(data); + + Button removeButton = new Button(buttonComp, SWT.PUSH); + removeButton.setText("Remove Current"); + removeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + IStructuredSelection selection = (IStructuredSelection) viewer + .getSelection(); + if (selection != null) { + AlertWord word = (AlertWord) selection.getFirstElement(); + ((List) viewer.getInput()).remove(word); + viewer.refresh(); + } + } + }); + data = new GridData(SWT.NONE, SWT.NONE, false, true); + removeButton.setLayoutData(data); + + viewer.getTable().addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + AlertWord word = (AlertWord) e.item.getData(); + colorEditor.getColorSelector() + .setColorValue( + new RGB(word.getRed(), word.getGreen(), word + .getBlue())); + stringEditor.setStringValue(word.getText()); + fontLabel.setText(word.getFont()); + fileEditor.setStringValue(word.getSoundPath()); + } + }); + viewer.setInput(CollaborationUtils.getAlertWords()); + } + + public boolean performOk() { + List words = (List) viewer.getInput(); + CollaborationUtils.saveAlertWords(words); + AlertWordWrapper wrapper = new AlertWordWrapper(); + wrapper.setAlertWords(words.toArray(new AlertWord[0])); + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection != null && connection.isConnected()) { + // refresh any open chats or sessions + connection.postEvent(wrapper); + } + return true; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + setDescription("Significant Words"); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferenceContentProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferenceContentProvider.java new file mode 100644 index 0000000000..e4152a7dc7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferenceContentProvider.java @@ -0,0 +1,65 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.prefs; + +import java.util.List; + +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationPreferenceContentProvider implements + IStructuredContentProvider { + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + oldInput = newInput; + viewer.refresh(); + } + + @Override + public Object[] getElements(Object inputElement) { + if (inputElement instanceof List) { + List list = (List) inputElement; + return list.toArray(); + } + return null; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferencePage.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferencePage.java new file mode 100644 index 0000000000..4d5730713e --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferencePage.java @@ -0,0 +1,100 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.prefs; + +import org.eclipse.jface.preference.BooleanFieldEditor; +import org.eclipse.jface.preference.FieldEditor; +import org.eclipse.jface.preference.FieldEditorPreferencePage; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPreferencePage; + +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.ui.Activator; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 27, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationPreferencePage extends FieldEditorPreferencePage + implements IWorkbenchPreferencePage { + + public CollaborationPreferencePage() { + super(GRID); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench) + */ + @Override + public void init(IWorkbench workbench) { + setPreferenceStore(Activator.getDefault().getPreferenceStore()); + setDescription("Collaboration User Interface Preferences"); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors + * () + */ + @Override + protected void createFieldEditors() { + FieldEditor notifications = new BooleanFieldEditor("notifications", + "Show Notifications", getFieldEditorParent()); + this.addField(notifications); + FieldEditor autojoinColl = new BooleanFieldEditor( + CollabPrefConstants.AUTO_JOIN, "Join Discussion On Login", + getFieldEditorParent()); + this.addField(autojoinColl); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.preference.FieldEditorPreferencePage#performOk() + */ + @Override + public boolean performOk() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection != null && connection.isConnected()) { + CollaborationConnection.getConnection().postEvent( + Activator.getDefault().getPreferenceStore()); + } + return super.performOk(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferencesLabelProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferencesLabelProvider.java new file mode 100644 index 0000000000..da4440c1e5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/prefs/CollaborationPreferencesLabelProvider.java @@ -0,0 +1,108 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.prefs; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.collaboration.ui.data.AlertWord; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class CollaborationPreferencesLabelProvider extends ColumnLabelProvider { + + private List colors = null; + + private List fonts = null; + + /** + * + */ + public CollaborationPreferencesLabelProvider() { + colors = new ArrayList(); + fonts = new ArrayList(); + } + + @Override + public String getText(Object element) { + AlertWord word = (AlertWord) element; + return word.getText(); + } + + @Override + public Color getForeground(Object element) { + AlertWord word = (AlertWord) element; + Color color = new Color(Display.getCurrent(), word.getRed(), + word.getGreen(), word.getBlue()); + colors.add(color); + return color; + } + + @Override + public Font getFont(Object element) { + AlertWord word = (AlertWord) element; + String fontString = word.getFont(); + Font font = null; + if (fontString != null) { + FontData data = StringConverter.asFontData(fontString); + font = new Font(Display.getCurrent(), data); + fonts.add(font); + } + return font; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.BaseLabelProvider#dispose() + */ + @Override + public void dispose() { + for (Font font : fonts) { + font.dispose(); + } + for (Color color : colors) { + color.dispose(); + } + super.dispose(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/AbstractSessionView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/AbstractSessionView.java new file mode 100644 index 0000000000..8cce57947c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/AbstractSessionView.java @@ -0,0 +1,618 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.preference.PreferenceConverter; +import org.eclipse.jface.resource.StringConverter; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.TextStyle; +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.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.progress.IWorkbenchSiteProgressService; + +import sun.audio.AudioData; +import sun.audio.AudioDataStream; +import sun.audio.AudioPlayer; +import sun.audio.AudioStream; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.CollaborationUtils; +import com.raytheon.uf.viz.collaboration.ui.actions.CopyTextAction; +import com.raytheon.uf.viz.collaboration.ui.actions.CutTextAction; +import com.raytheon.uf.viz.collaboration.ui.actions.PasteTextAction; +import com.raytheon.uf.viz.collaboration.ui.actions.PopupNotifier; +import com.raytheon.uf.viz.collaboration.ui.data.AlertWord; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveFloatingView; + +/** + * This performs most of the work for creating a View for a peer-to-peer or + * multi-user session. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 16, 2012 244        rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public abstract class AbstractSessionView extends CaveFloatingView { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(AbstractSessionView.class); + + private static final String SESSION_IMAGE_KEY = "sessionId.key"; + + /** + * Mapping of images used in the view so they are not constantly created and + * allowing them to be disposed. + */ + protected Map imageMap; + + private static int SASH_WIDTH = 5; + + private static int SASH_COLOR = SWT.COLOR_DARK_GRAY; + + protected StyledText messagesText; + + private StyledText composeText; + + private UserId[] userIds = null; + + protected SessionMsgArchive msgArchive; + + private List alertWords = null; + + private AudioDataStream ads = null; + + private Map fonts = null; + + private Map colors = null; + + private SearchComposite searchComp; + + private Action searchAction; + + protected abstract String getSessionImageName(); + + protected abstract String getSessionName(); + + public abstract void sendMessage(); + + protected abstract void setMessageLabel(Composite comp); + + public AbstractSessionView() { + imageMap = new HashMap(); + userIds = CollaborationUtils.getIds(); + fonts = new HashMap(); + colors = new HashMap(); + } + + protected void initComponents(Composite parent) { + Composite sashComp = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + sashComp.setLayout(layout); + sashComp.setLayoutData(data); + + Color sashColor = Display.getCurrent().getSystemColor(SASH_COLOR); + + SashForm sashForm = new SashForm(sashComp, SWT.VERTICAL); + layout = new GridLayout(1, false); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + sashForm.setLayout(layout); + sashForm.setLayoutData(data); + sashForm.setBackground(sashColor); + sashForm.setSashWidth(SASH_WIDTH); + + populateSashForm(sashForm); + } + + protected void initMessageArchive() { + msgArchive = createMessageArchive(); + } + + /** + * A Subclass must override this method to set sashForm's weight and to add + * other components. + * + * @param sashForm + */ + protected void populateSashForm(SashForm sashForm) { + createMessagesComp(sashForm); + createComposeComp(sashForm); + } + + private void createMessagesComp(Composite parent) { + Composite messagesComp = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + messagesComp.setLayout(layout); + setMessageLabel(messagesComp); + + searchComp = new SearchComposite(messagesComp, SWT.BORDER); + searchComp.hide(true); + + messagesText = new StyledText(messagesComp, SWT.MULTI | SWT.WRAP + | SWT.READ_ONLY | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + messagesText.setLayoutData(new GridData(GridData.FILL_BOTH)); + + messagesComp.addKeyListener(searchComp.getSearchKeyListener()); + + messagesText.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + // is it a visible character + if (Character.isISOControl(e.character) == false) { + composeText.setFocus(); + composeText.append(Character.toString(e.character)); + composeText.setCaretOffset(composeText.getText().length()); + } + } + }); + // here need to grab the font from preferences and use that font + messagesText.setFont(new Font(Display.getCurrent(), PreferenceConverter + .getFontData(Activator.getDefault().getPreferenceStore(), + "font"))); + + searchComp.setSearchText(messagesText); + + // adding a menu item so that Paste can be found when clicking on the + // composeText styledtext + MenuManager menuMgr = new MenuManager(); + menuMgr.add(new CopyTextAction(messagesText)); + Menu menu = menuMgr.createContextMenu(messagesText); + messagesText.setMenu(menu); + } + + protected void createComposeComp(Composite parent) { + Composite composeComp = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + composeComp.setLayout(layout); + + Label label = new Label(composeComp, SWT.NONE); + label.setText("Compose:"); + composeText = new StyledText(composeComp, SWT.MULTI | SWT.WRAP + | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + composeText.setLayoutData(new GridData(GridData.FILL_BOTH)); + composeText.setToolTipText("Enter message here"); + composeText.addKeyListener(new KeyListener() { + private boolean keyPressed; + + @Override + public void keyReleased(KeyEvent e) { + if (e.keyCode == SWT.SHIFT) { + keyPressed = false; + } + // do nothing, all done on key pressed + } + + @Override + public void keyPressed(KeyEvent e) { + if (!keyPressed + && (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR)) { + sendMessage(); + } + if (e.keyCode == SWT.SHIFT) { + keyPressed = true; + } + if (searchComp != null) { + searchComp.search(e); + } + } + }); + + // adding a menu item so that Paste can be found when clicking on the + // composeText styledtext + MenuManager menuMgr = new MenuManager(); + menuMgr.add(new CopyTextAction(composeText)); + menuMgr.add(new PasteTextAction(composeText)); + menuMgr.add(new CutTextAction(composeText)); + + Menu menu = menuMgr.createContextMenu(composeText); + composeText.setMenu(menu); + } + + private Image getImage() { + Image image = imageMap.get(SESSION_IMAGE_KEY); + if (image == null) { + image = IconUtil.getImageDescriptor( + Activator.getDefault().getBundle(), getSessionImageName()) + .createImage(); + if (image != null) { + imageMap.put(SESSION_IMAGE_KEY, image); + } + } + return image; + } + + /** + * Get the composed message and clear the text. + * + * @return message + */ + protected String getComposedMessage() { + String message = composeText.getText(); + int returnIndex = message.lastIndexOf("\n"); + message = message.substring(0, returnIndex); + composeText.setText(""); + composeText.setCaretOffset(0); + return message; + } + + /** + * Append the message into the message text field. + * + * @param message + */ + public void appendMessage(IMessage message) { + UserId userId = (UserId) message.getFrom(); + long timestamp = message.getTimeStamp(); + String body = message.getBody(); + String subject = message.getSubject(); + appendMessage(userId, timestamp, body, subject); + } + + public void appendMessage(final UserId userId, final long timestamp, + final String body, final String subject) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null || body.length() == 0) { + // this can occur if the session has closed this method was + // waiting to run async, in that case just ignore the + // message. + return; + } + + IWorkbenchSiteProgressService service = (IWorkbenchSiteProgressService) getSite() + .getAdapter(IWorkbenchSiteProgressService.class); + service.warnOfContentChange(); + + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(timestamp); + String time = String.format("%1$tI:%1$tM:%1$tS %1$Tp", cal); + + String name = connection.getContactsManager().getDisplayName( + userId); + + UserId myUser = connection.getUser(); + if (!myUser.equals(userId) + && Activator.getDefault().getPreferenceStore() + .getBoolean("notifications")) { + createNotifier(name, time, body); + } + + StringBuilder sb = new StringBuilder(); + if (messagesText.getCharCount() != 0) { + sb.append("\n"); + } + sb.append("(").append(time).append(") "); + int offset = sb.length(); + + sb.append(name).append(": ").append(body); + // here is the place to put the font and color changes for + // keywords + // read in localization file once and then don't read in again, + // per + // chat room? + List alertWords = retrieveAlertWords(); + List ranges = new ArrayList(); + if (alertWords != null) { + for (AlertWord keyword : alertWords) { + String text = keyword.getText().toLowerCase(); + if (sb.toString().toLowerCase().contains(text)) { + String lowerCase = sb.toString().toLowerCase(); + // getting the current length of the text + int currentLength = messagesText.getCharCount(); + int index = lowerCase.indexOf(text); + while (index >= 0) { + Font font = null; + // storing off fonts so we don't leak + if (fonts.containsKey(keyword.getFont())) { + font = fonts.get(keyword.getFont()); + } else { + FontData fd = StringConverter + .asFontData(keyword.getFont()); + font = new Font(Display.getCurrent(), fd); + fonts.put(keyword.getFont(), font); + } + + RGB rgb = new RGB(keyword.getRed(), keyword + .getGreen(), keyword.getBlue()); + Color color = null; + // using the stored colors so we don't leak + if (colors.containsKey(rgb)) { + color = colors.get(rgb); + } else { + color = new Color(Display.getCurrent(), rgb); + colors.put(rgb, color); + } + TextStyle style = new TextStyle(font, color, + null); + StyleRange keywordRange = new StyleRange(style); + keywordRange.start = currentLength + index; + keywordRange.length = keyword.getText() + .length(); + + ranges.add(keywordRange); + // compare to see if this position is already + // styled + List rnges = new ArrayList(); + rnges.addAll(ranges); + for (StyleRange range : rnges) { + if (range.start <= keywordRange.start + && (range.start + range.length) >= keywordRange.start) { + if (keywordRange != range) { + if (range.length < keywordRange.length) { + ranges.remove(range); + } else { + ranges.remove(keywordRange); + } + } + } + } + + // only execute things if the same user didn't + // type it + if (!myUser.equals(userId)) { + executeSightsSounds(keyword); + } + // need to handle all instances of the keyword + // within the chat + index = lowerCase.indexOf(text, text.length() + + index); + } + } + } + } + + styleAndAppendText(sb, offset, name, userId, subject, ranges); + msgArchive.archive(sb.toString()); + searchComp.appendText(sb.toString()); + } + }); + } + + protected abstract void styleAndAppendText(StringBuilder sb, int offset, + String name, UserId userId, String subject, List ranges); + + protected abstract void styleAndAppendText(StringBuilder sb, int offset, + String name, UserId userId, List ranges, Color color); + + /** + * Find keys words in body of message starting at offset. /** + * + * @param builder + * @param offset + * @return alertWords + */ + protected List retrieveAlertWords() { + if (alertWords == null) { + alertWords = CollaborationUtils.getAlertWords(); + } + return alertWords; + } + + /** + * Place holder must override to do something. + */ + protected void executeSightsSounds(AlertWord word) { + String filename = word.getSoundPath(); + if (filename == null || filename.isEmpty()) { + return; + } + File soundFile = new File(filename); + InputStream in; + AudioStream as = null; + AudioData data = null; + try { + if (ads != null) { + AudioPlayer.player.stop(ads); + } + in = new FileInputStream(soundFile); + as = new AudioStream(in); + data = as.getData(); + ads = new AudioDataStream(data); + AudioPlayer.player.start(ads); + } catch (FileNotFoundException e) { + statusHandler.handle(Priority.PROBLEM, "Unable to find sound file", + e); + } catch (IOException e) { + statusHandler.handle(Priority.PROBLEM, "Unable to read sound file", + e); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets + * .Composite) + */ + @Override + public void createPartControl(Composite parent) { + parent.setLayout(new GridLayout()); + super.createPartControl(parent); + setTitleImage(getImage()); + setPartName(getSessionName()); + initComponents(parent); + createActions(); + } + + private void createActions() { + searchAction = new Action("Search") { + @Override + public void run() { + searchComp.toggleVisibility(); + } + }; + IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); + mgr.add(searchAction); + searchAction.setImageDescriptor(IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "find.gif")); + } + + @Override + public void dispose() { + for (Image im : imageMap.values()) { + im.dispose(); + } + + for (Font font : fonts.values()) { + font.dispose(); + } + + for (Color color : colors.values()) { + color.dispose(); + } + + imageMap.clear(); + imageMap = null; + alertWords = null; + if (msgArchive != null) { + msgArchive.close(); + msgArchive = null; + } + + super.dispose(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.WorkbenchPart#setFocus() + */ + @Override + public void setFocus() { + composeText.setFocus(); + } + + private void createNotifier(String id, String time, String body) { + String titleText = "(" + time + ") " + id; + PopupNotifier.notify(titleText, body); + } + + @Subscribe + public void changeFont(FontData data) { + messagesText.setFont(new Font(Display.getCurrent(), data)); + } + + /** + * @return the userIds + */ + public UserId[] getUserIds() { + return userIds; + } + + /** + * @param userIds + * the userIds to set + */ + public void setUserIds(UserId[] userIds) { + this.userIds = userIds; + } + + public void setAlertWords(List words) { + alertWords = words; + } + + protected abstract SessionMsgArchive createMessageArchive(); + + protected void sendErrorMessage(StringBuilder sb) { + Color color = Display.getCurrent().getSystemColor(SWT.COLOR_RED); + sendGenericMessage(sb, color); + } + + protected void sendSystemMessage(StringBuilder sb) { + Color color = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + sendGenericMessage(sb, color); + } + + private void sendGenericMessage(final StringBuilder string, + final Color color) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + Calendar cal = Calendar.getInstance(); + cal.setTimeInMillis(System.currentTimeMillis()); + String time = String.format("%1$tI:%1$tM:%1$tS %1$Tp", cal); + string.insert(0, "(" + time + ") : "); + if (messagesText.getCharCount() != 0) { + string.insert(0, "\n"); + } + StyleRange range = new StyleRange(messagesText.getCharCount(), + string.length(), color, null, SWT.BOLD); + List ranges = new ArrayList(); + ranges.add(range); + styleAndAppendText(string, 0, string.toString(), null, ranges, + color); + msgArchive.archiveLine(string.toString()); + searchComp.appendText(string.toString()); + } + }); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionAction.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionAction.java new file mode 100644 index 0000000000..3f56956a1c --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionAction.java @@ -0,0 +1,65 @@ +package com.raytheon.uf.viz.collaboration.ui.session; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.PartInitException; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class CollaborationSessionAction extends AbstractHandler { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CollaborationSessionAction.class); + + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + try { + CaveWorkbenchPageManager.getActiveInstance().showView( + CollaborationSessionView.ID); + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to open collaboration session", e); + } + return event; + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java new file mode 100644 index 0000000000..283056971a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/CollaborationSessionView.java @@ -0,0 +1,775 @@ +package com.raytheon.uf.viz.collaboration.ui.session; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.ActionContributionItem; +import org.eclipse.jface.action.ControlContribution; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.ColorDialog; +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.ToolItem; +import org.eclipse.ui.IPartListener; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.PartInitException; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.identity.invite.ColorPopulator; +import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole; +import com.raytheon.uf.viz.collaboration.comm.provider.TransferRoleCommand; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer.IRemoteDisplayChangedListener; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer.RemoteDisplay; +import com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer.RemoteDisplayChangeType; +import com.raytheon.uf.viz.collaboration.display.data.ColorChangeEvent; +import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager; +import com.raytheon.uf.viz.collaboration.display.data.SessionContainer; +import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr; +import com.raytheon.uf.viz.collaboration.display.rsc.SelfAddingSystemResourceListener; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingEvent; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingEvent.CollaborationEventType; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingResource; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingResourceData; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.core.ContextManager; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; +import com.raytheon.uf.viz.drawing.DrawingToolLayer; +import com.raytheon.uf.viz.drawing.DrawingToolLayer.DrawMode; +import com.raytheon.viz.ui.input.EditableManager; + +/** + * View class for a collaboration session + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class CollaborationSessionView extends SessionView implements + IPartListener, IRemoteDisplayChangedListener { + public static final String ID = "com.raytheon.uf.viz.collaboration.CollaborationSession"; + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CollaborationSessionView.class); + + private static final String COLLABORATION_SESSION_IMAGE_NAME = "messages.gif"; + + private Runnable actionUpdater = new Runnable() { + @Override + public void run() { + updateToolItems(); + } + }; + + private Action colorChangeAction; + + private ActionContributionItem drawAction; + + private ActionContributionItem undoAction; + + private ActionContributionItem redoAction; + + private ActionContributionItem eraseAction; + + private ActionContributionItem clearAction; + + private ActionContributionItem lockAction; + + private ControlContribution noEditorAction; + + private ISharedDisplaySession session; + + private IRemoteDisplayContainer container; + + private IRenderableDisplay currentDisplay; + + private boolean locked = false; + + private DrawMode drawMode = DrawMode.NONE; + + private Map listeners = new IdentityHashMap(); + + public IRemoteDisplayContainer getDisplayContainer() { + return container; + } + + public CollaborationDrawingResource getCurrentDrawingResource() { + CollaborationDrawingResource currentResource = null; + if (currentDisplay != null) { + for (CollaborationDrawingResource resource : currentDisplay + .getDescriptor() + .getResourceList() + .getResourcesByTypeAsType( + CollaborationDrawingResource.class)) { + currentResource = resource; + break; + } + } + return currentResource; + } + + private DrawingToolLayer getCurrentLayer() { + CollaborationDrawingResource resource = getCurrentDrawingResource(); + if (resource != null) { + return resource.getDrawingLayerFor(resource.getMyUser()); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite) + */ + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + site.getPage().addPartListener(this); + SessionContainer sc = SharedDisplaySessionMgr + .getSessionContainer(sessionId); + if (sc != null) { + session = sc.getSession(); + container = sc.getDisplayContainer(); + if (container != null) { + container.addRemoteDisplayChangedListener(this); + RemoteDisplay remoteDisplay = container.getActiveDisplay(); + if (remoteDisplay != null) { + remoteDisplayChanged(container.getActiveDisplay(), + RemoteDisplayChangeType.ACTIVATED); + } + } + } + } + + protected void createActions() { + super.createActions(); + + colorChangeAction = new Action("Change Color...") { + @Override + public void run() { + ColorDialog dlg = new ColorDialog(Display.getCurrent() + .getActiveShell()); + RGB rgb = dlg.open(); + if (rgb != null) { + IStructuredSelection selection = (IStructuredSelection) usersTable + .getSelection(); + IUser entry = (IUser) selection.getFirstElement(); + ColorChangeEvent event = new ColorChangeEvent( + IDConverter.convertFrom(entry), rgb); + try { + session.sendObjectToVenue(event); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to send color change to venue", e); + } + } + } + }; + + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.views.CaveFloatingView#createToolbarButton() + */ + @Override + protected void createToolbarButton() { + super.createToolbarButton(); + + drawAction = new ActionContributionItem(new Action("Draw", SWT.TOGGLE) { + @Override + public void run() { + toggleDrawMode(DrawMode.DRAW); + } + }); + drawAction.getAction().setImageDescriptor( + IconUtil.getImageDescriptor( + com.raytheon.uf.viz.drawing.Activator.getDefault() + .getBundle(), "draw.gif")); + CollaborationDrawingResource resource = getCurrentDrawingResource(); + if (resource != null) { + addEditableListener(resource.getResourceData()); + } + undoAction = new ActionContributionItem(new Action("Undo") { + @Override + public void run() { + DrawingToolLayer layer = getCurrentLayer(); + if (layer != null) { + layer.undo(); + } + updateToolItems(); + } + }); + undoAction.getAction().setImageDescriptor( + IconUtil.getImageDescriptor( + com.raytheon.uf.viz.drawing.Activator.getDefault() + .getBundle(), "undo.gif")); + + redoAction = new ActionContributionItem(new Action("Redo") { + @Override + public void run() { + DrawingToolLayer layer = getCurrentLayer(); + if (layer != null) { + layer.redo(); + } + updateToolItems(); + } + }); + redoAction.getAction().setImageDescriptor( + IconUtil.getImageDescriptor( + com.raytheon.uf.viz.drawing.Activator.getDefault() + .getBundle(), "redo.gif")); + + eraseAction = new ActionContributionItem( + new Action("Erase", SWT.TOGGLE) { + @Override + public void run() { + toggleDrawMode(DrawMode.ERASE); + } + }); + eraseAction.getAction().setImageDescriptor( + IconUtil.getImageDescriptor( + com.raytheon.uf.viz.drawing.Activator.getDefault() + .getBundle(), "eraser.png")); + + clearAction = new ActionContributionItem(new Action("Clear") { + public void run() { + DrawingToolLayer layer = getCurrentLayer(); + if (layer != null) { + layer.clear(); + } + updateToolItems(); + }; + }); + clearAction.getAction().setImageDescriptor( + IconUtil.getImageDescriptor( + com.raytheon.uf.viz.drawing.Activator.getDefault() + .getBundle(), "remove.gif")); + + lockAction = new ActionContributionItem(new Action( + "Lock Collaborators", SWT.TOGGLE) { + public void run() { + CollaborationDrawingResource resource = getCurrentDrawingResource(); + if (resource != null) { + resource.setLockingDrawing(((ToolItem) lockAction + .getWidget()).getSelection()); + locked = resource.isLockingDrawing(); + updateToolItems(); + } + }; + }); + lockAction.getAction().setImageDescriptor( + IconUtil.getImageDescriptor(Activator.getDefault().getBundle(), + "lock.gif")); + + noEditorAction = new ControlContribution("noEditorAction") { + + @Override + protected Control createControl(Composite parent) { + Label l = new Label(parent, SWT.NONE); + l.setImage(IconUtil.getImageDescriptor( + Activator.getDefault().getBundle(), "warning.gif") + .createImage()); + if (session.getCurrentSessionLeader().equals( + CollaborationConnection.getConnection().getUser())) { + l.setToolTipText("You are not viewing a shared display"); + } else { + l.setToolTipText("The session leader is not viewing a shared display."); + } + return l; + } + }; + + ToolBarManager mgr = (ToolBarManager) getViewSite().getActionBars() + .getToolBarManager(); + + mgr.insert(mgr.getSize() - 1, new Separator()); + mgr.insert(mgr.getSize() - 1, drawAction); + + mgr.insert(mgr.getSize() - 1, undoAction); + mgr.insert(mgr.getSize() - 1, redoAction); + mgr.insert(mgr.getSize() - 1, clearAction); + mgr.insert(mgr.getSize() - 1, eraseAction); + mgr.insert(mgr.getSize() - 1, lockAction); + mgr.insert(mgr.getSize() - 1, new Separator()); + + updateToolItems(); + } + + private void toggleDrawMode(DrawMode mode) { + if (mode != DrawMode.NONE) { + CollaborationDrawingResource resource = getCurrentDrawingResource(); + DrawingToolLayer layer = resource != null ? resource + .getDrawingLayerFor(resource.getMyUser()) : null; + if (layer != null) { + if (layer.getDrawMode() == mode) { + layer.setDrawMode(DrawMode.NONE); + } else { + layer.setDrawMode(mode); + } + drawMode = layer.getDrawMode(); + + // make editable so mouse actions work on it and not others + if (resource.isSessionLeader()) { + EditableManager.makeEditable(resource, true); + } + updateToolItems(); + } + } + } + + public void updateToolItems() { + ToolBarManager mgr = (ToolBarManager) getViewSite().getActionBars() + .getToolBarManager(); + mgr.remove(noEditorAction); + if (currentDisplay == null) { + mgr.insert(0, noEditorAction); + } + CollaborationDrawingResource currentResource = getCurrentDrawingResource(); + DrawingToolLayer layer = null; + if (currentResource != null) { + layer = currentResource.getDrawingLayerFor(currentResource + .getMyUser()); + } + if (layer != null && currentResource.isSessionLeader()) { + lockAction.getAction().setEnabled(true); + } + if (layer != null + && (locked == false || currentResource.isSessionLeader())) { + drawAction.getAction().setEnabled(true); + undoAction.getAction().setEnabled(layer.canUndo()); + redoAction.getAction().setEnabled(layer.canRedo()); + clearAction.getAction().setEnabled(layer.canClear()); + eraseAction.getAction().setEnabled(true); + switch (layer.getDrawMode()) { + case DRAW: + drawAction.getAction().setChecked( + currentResource.getCapability(EditableCapability.class) + .isEditable()); + eraseAction.getAction().setChecked(false); + break; + case ERASE: + drawAction.getAction().setChecked(false); + eraseAction.getAction().setChecked( + currentResource.getCapability(EditableCapability.class) + .isEditable()); + break; + case NONE: + drawAction.getAction().setChecked(false); + eraseAction.getAction().setChecked(false); + break; + } + lockAction.getAction().setChecked( + currentResource.isLockingDrawing()); + } else { + drawAction.getAction().setEnabled(false); + undoAction.getAction().setEnabled(false); + redoAction.getAction().setEnabled(false); + clearAction.getAction().setEnabled(false); + eraseAction.getAction().setEnabled(false); + lockAction.getAction().setEnabled(false); + } + getViewSite().getActionBars().getToolBarManager().update(true); + } + + /** + * @return the redoAction + */ + public ActionContributionItem getRedoAction() { + return redoAction; + } + + /** + * @return the undoAction + */ + public ActionContributionItem getUndoAction() { + return undoAction; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#initColorManager + * () + */ + @Override + protected void initColorManager() { + colorManager = SharedDisplaySessionMgr.getSessionContainer(sessionId) + .getColorManager(); + } + + @Subscribe + public void refreshAfterTransfer(TransferRoleCommand command) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + usersTable.refresh(); + } + }); + } + + @Override + protected String getSessionImageName() { + return COLLABORATION_SESSION_IMAGE_NAME; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#sendMessage() + */ + @Override + public void sendMessage() { + String message = getComposedMessage(); + if (message.length() > 0) { + try { + UserId id = CollaborationConnection.getConnection().getUser(); + appendMessage(id, System.currentTimeMillis(), message, null); + ((IVenueSession) session).sendChatMessage(message); + } catch (CollaborationException e) { + statusHandler.handle(Priority.ERROR, + "Unable to send chat message", e); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#fillContextMenu + * (org.eclipse.jface.action.IMenuManager) + */ + @Override + protected void fillContextMenu(IMenuManager manager) { + super.fillContextMenu(manager); + if (session.hasRole(SharedDisplayRole.DATA_PROVIDER) + || session.hasRole(SharedDisplayRole.SESSION_LEADER)) { + if (session.hasRole(SharedDisplayRole.SESSION_LEADER)) { + manager.add(new Separator()); + manager.add(colorChangeAction); + } + } + } + + @Subscribe + public void modifyColors(ColorPopulator populator) { + SessionColorManager colorMan = SharedDisplaySessionMgr + .getSessionContainer(sessionId).getColorManager(); + for (Entry entry : populator.getColors().entrySet()) { + colorMan.setColorForUser(entry.getKey(), entry.getValue()); + } + VizApp.runAsync(new Runnable() { + @Override + public void run() { + usersTable.refresh(); + } + }); + } + + @Subscribe + public void modifyColors(ColorChangeEvent event) { + SharedDisplaySessionMgr.getSessionContainer(sessionId) + .getColorManager() + .setColorForUser(event.getUserName(), event.getColor()); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + usersTable.refresh(); + } + }); + } + + @Subscribe + public void collaborationEvent(CollaborationDrawingEvent event) { + // we need to check here for the event type otherwise it may not get set + // before this is called (since it depends on the event bus), this + // handles locking and unlocking of the toolbar in the view + if (event.getType() == CollaborationEventType.LOCK_USERS) { + locked = true; + } else if (event.getType() == CollaborationEventType.UNLOCK_USERS) { + locked = false; + } + VizApp.runAsync(actionUpdater); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * setMessageLabel(org.eclipse.swt.widgets.Label) + */ + @Override + protected void setMessageLabel(Composite comp) { + Label label = new Label(comp, SWT.NONE); + StringBuilder labelInfo = new StringBuilder(); + if (session != null) { + IVenueInfo info = ((IVenueSession) session).getVenue().getInfo(); + labelInfo.append(info.getVenueSubject()); + label.setToolTipText(info.getVenueSubject()); + } + label.setText(labelInfo.toString()); + } + + public String getSessionId() { + return session.getSessionId(); + } + + @Override + public void dispose() { + SharedDisplaySessionMgr.exitSession(session.getSessionId()); + session.close(); + super.dispose(); + getSite().getPage().removePartListener(this); + if (container != null) { + container.removeRemoteDisplayChangedListener(this); + } + } + + // =================== Context activation code =================== + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart) + */ + @Override + public void partActivated(IWorkbenchPart part) { + // only done if we care about the part that was activated + if (container != null && container.getActiveDisplayEditor() == part) { + ContextManager + .getInstance(getSite().getPage().getWorkbenchWindow()) + .activateContexts(this); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart + * ) + */ + @Override + public void partBroughtToTop(IWorkbenchPart part) { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart) + */ + @Override + public void partClosed(IWorkbenchPart part) { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart + * ) + */ + @Override + public void partDeactivated(IWorkbenchPart part) { + // only done if we care about the part that was deactivated + if (container != null && container.getActiveDisplayEditor() == part) { + ContextManager + .getInstance(getSite().getPage().getWorkbenchWindow()) + .deactivateContexts(this); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.ui.IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart) + */ + @Override + public void partOpened(IWorkbenchPart part) { + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer. + * IRemoteDisplayChangedListener + * #remoteDisplayChanged(com.raytheon.uf.viz.core + * .drawables.IRenderableDisplay, + * com.raytheon.uf.viz.collaboration.display.IRemoteDisplayContainer + * .RemoteDisplayChangeType) + */ + @Override + public void remoteDisplayChanged(RemoteDisplay remoteDisplay, + RemoteDisplayChangeType changeType) { + if (remoteDisplay == null) { + currentDisplay = null; + VizApp.runAsync(actionUpdater); + return; + } + IRenderableDisplay display = remoteDisplay.getDisplay(); + int displayId = remoteDisplay.getDisplayId(); + switch (changeType) { + case CREATED: + if (listeners.containsKey(display) == false) { + CollaborationDrawingResourceData resourceData = new CollaborationDrawingResourceData(); + resourceData.setSessionId(sessionId); + resourceData.setDisplayId(displayId); + addEditableListener(resourceData); + try { + listeners.put(display, + new SelfAddingSystemResourceListener(resourceData, + display.getDescriptor())); + + CollaborationDrawingResource resource = getCurrentDrawingResource(); + if (resource != null) { + DrawingToolLayer layer = getCurrentLayer(); + // on create, session leader will remove the + // drawing/erasing ability + // on create, participants will keep the drawing/erasing + // ability if it is active + if (resource.isSessionLeader()) { + layer.setDrawMode(DrawMode.NONE); + } else { + layer.setDrawMode(drawMode); + } + drawMode = layer.getDrawMode(); + resource.setLockingDrawing(locked); + } + + display.refresh(); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + break; + case ACTIVATED: + if (listeners.containsKey(display) == false) { + remoteDisplayChanged(remoteDisplay, + RemoteDisplayChangeType.CREATED); + } + + // grab the current resource (before we change the display) so that + // we can set the DrawMode to DrawMode.NONE, therefore preventing + // drawing on the active editor and having it paint to the + // non-active editor + CollaborationDrawingResource resource = getCurrentDrawingResource(); + if (resource != null) { + DrawingToolLayer layer = getCurrentLayer(); + switch (layer.getDrawMode()) { + case DRAW: + layer.doneDrawing(); + break; + case ERASE: + layer.doneErasing(); + break; + } + layer.setDrawMode(DrawMode.NONE); + } + currentDisplay = display; + + resource = getCurrentDrawingResource(); + // on activate, all users will keep the current ability, drawing, + // erasing, or none + if (resource != null) { + DrawingToolLayer layer = getCurrentLayer(); + layer.setDrawMode(drawMode); + resource.setLockingDrawing(locked); + } + VizApp.runAsync(actionUpdater); + break; + case DISPOSED: + SelfAddingSystemResourceListener listener = listeners + .remove(display); + if (listener != null) { + listener.dispose(); + } + if (display == currentDisplay) { + currentDisplay = null; + VizApp.runAsync(actionUpdater); + } + break; + } + } + + /** + * Listener provides the view with information that the resource has become + * editable or not, which will affect any mouse handlers associated with it + * + * @param resourceData + */ + private void addEditableListener( + CollaborationDrawingResourceData resourceData) { + resourceData.addChangeListener(new IResourceDataChanged() { + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.CAPABILITY + && object instanceof EditableCapability) { + VizApp.runAsync(actionUpdater); + } + } + }); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/IPrintableView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/IPrintableView.java new file mode 100644 index 0000000000..968671077f --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/IPrintableView.java @@ -0,0 +1,60 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import org.eclipse.swt.custom.StyledText; +import org.eclipse.ui.IViewPart; + +/** + * An IViewPart that has printable content. Printable content must + * be in the form of a StyledText control. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 5, 2012            dgilling     Initial creation
+ * 
+ * 
+ * + * @author dgilling + * @version 1.0 + */ + +public interface IPrintableView extends IViewPart { + + /** + * The StyledText control that contains the content to be + * printed. Developers should take care to ensure this never returns null. + * + * @return The content to be printed. + */ + public abstract StyledText getStyledText(); + + /** + * Defines the text that will be used for the header of the printed + * document. + * + * @return Header contents. + */ + public abstract String getHeaderText(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/ISearchText.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/ISearchText.java new file mode 100644 index 0000000000..5ee8a9fa6b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/ISearchText.java @@ -0,0 +1,50 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import org.eclipse.swt.custom.StyledText; + +/** + * Interface for searching through a styled text + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 19, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public interface ISearchText { + + void select(int start, int end); + + void reachedLast(); + + void reachedFirst(); + + StyledText getStyledText(); +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/ParticipantsLabelProvider.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/ParticipantsLabelProvider.java new file mode 100644 index 0000000000..d501ab28a9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/ParticipantsLabelProvider.java @@ -0,0 +1,255 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.session.SharedDisplaySession; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager; +import com.raytheon.uf.viz.collaboration.ui.AbstractUserLabelProvider; + +/** + * Generate the Participant's label and icon image. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 24, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class ParticipantsLabelProvider extends AbstractUserLabelProvider { + + protected String sessionId = null; + + private List enabledSites; + + protected Map colors = new HashMap(); + + private SessionColorManager manager; + + private Font boldFont; + + private Font underlinedFont; + + private Font combinedFont; + + public ParticipantsLabelProvider() { + + } + + @Override + public void dispose() { + super.dispose(); + if (colors != null) { + for (Color col : colors.values()) { + col.dispose(); + } + colors.clear(); + } + + if (boldFont != null && !boldFont.isDisposed()) { + boldFont.dispose(); + boldFont = null; + } + if (underlinedFont != null && !underlinedFont.isDisposed()) { + underlinedFont.dispose(); + underlinedFont = null; + } + if (combinedFont != null && !combinedFont.isDisposed()) { + combinedFont.dispose(); + combinedFont = null; + } + } + + @Override + public Font getFont(Object element) { + if (!(element instanceof IUser)) { + return null; + } + IUser user = (IUser) element; + boolean leader = isSessionLeader(user); + boolean provider = isDataProvider(user); + if (leader && provider) { + if (combinedFont == null) { + Font currFont = Display.getCurrent().getSystemFont(); + combinedFont = new Font(Display.getCurrent(), + currFont.toString(), + currFont.getFontData()[0].getHeight(), SWT.BOLD + | SWT.ITALIC); + } + return combinedFont; + } else if (leader) { + if (boldFont == null) { + Font currFont = Display.getCurrent().getSystemFont(); + boldFont = new Font(Display.getCurrent(), currFont.toString(), + currFont.getFontData()[0].getHeight(), SWT.BOLD); + } + return boldFont; + } else if (provider) { + if (underlinedFont == null) { + Font currFont = Display.getCurrent().getSystemFont(); + underlinedFont = new Font(Display.getCurrent(), + currFont.toString(), + currFont.getFontData()[0].getHeight(), SWT.ITALIC); + } + return underlinedFont; + } + return null; + } + + @Override + public Color getForeground(Object element) { + if (!(element instanceof IUser)) { + return null; + } + IUser user = ((IUser) element); + UserId userId = IDConverter.convertFrom(user); + RGB rgb = manager.getColorFromUser(userId); + if (rgb == null) { + rgb = new RGB(0, 0, 0); + } + Color color = colors.get(rgb); + if (color == null) { + color = new Color(Display.getCurrent(), rgb); + colors.put(rgb, color); + } + return color; + } + + /** + * @param sessionId + * the sessionId to set + */ + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + protected ISession getSession() { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + return null; + } + return connection.getSession(sessionId); + } + + protected boolean isSessionLeader(IUser user) { + ISession session = getSession(); + if (session instanceof SharedDisplaySession) { + UserId id = IDConverter.convertFrom(user); + UserId leader = ((SharedDisplaySession) session) + .getCurrentSessionLeader(); + return id.equals(leader); + } + return false; + } + + protected boolean isDataProvider(IUser user) { + ISession session = getSession(); + if (session instanceof SharedDisplaySession) { + UserId id = IDConverter.convertFrom(user); + UserId provider = ((SharedDisplaySession) session) + .getCurrentDataProvider(); + return id.equals(provider); + } + return false; + } + + @Override + public String getToolTipText(Object element) { + String toolTip = super.getToolTipText(element); + if (toolTip == null) { + return null; + } + StringBuilder builder = new StringBuilder(toolTip); + IUser user = (IUser) element; + IPresence presence = getPresence(user); + if (presence != null) { + String site = String.valueOf(presence.getProperties().get( + SiteConfigInformation.SITE_NAME)); + if (enabledSites != null && enabledSites.contains(site)) { + builder.append("\n").append("Subscribed"); + } + } + ISession session = getSession(); + if (session instanceof SharedDisplaySession) { + UserId id = IDConverter.convertFrom(user); + boolean isSessionLeader = id + .equals(((SharedDisplaySession) session) + .getCurrentSessionLeader()); + boolean isDataProvider = id.equals(((SharedDisplaySession) session) + .getCurrentDataProvider()); + if (isSessionLeader || isDataProvider) { + // TODO if transferring control is ever desired and implemented + // we need to distinguish these. Until then, Leader works fine. + builder.append("\nLeader"); + // if (isSessionLeader) { + // builder.append("\nSession Leader"); + // } + // if (isDataProvider) { + // builder.append("\nData Provider"); + // } + } + } + return builder.toString(); + } + + protected void setEnabledSites(List enabledSites) { + this.enabledSites = enabledSites; + } + + /** + * @param manager + * the manager to set + */ + public void setManager(SessionColorManager manager) { + this.manager = manager; + } + + @Override + protected IPresence getPresence(IUser user) { + IVenueSession session = (IVenueSession) getSession(); + return session.getVenue().getPresence(user); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java new file mode 100644 index 0000000000..537f89014d --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/PeerToPeerView.java @@ -0,0 +1,309 @@ +package com.raytheon.uf.viz.collaboration.ui.session; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.List; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence.Type; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.IPeerToPeer; +import com.raytheon.uf.viz.collaboration.comm.identity.user.IQualifiedID; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PeerToPeerView extends AbstractSessionView implements + IPrintableView { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(PeerToPeerView.class); + + private static final String PEER_TO_PEER_IMAGE_NAME = "chats.gif"; + + public static final String ID = "com.raytheon.uf.viz.collaboration.PeerToPeerView"; + + private static Color userColor = null; + + private static Color chatterColor = null; + + private static Color black = null; + + private IQualifiedID peer; + + private boolean online = true; + + public PeerToPeerView() { + super(); + userColor = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE); + chatterColor = Display.getCurrent().getSystemColor(SWT.COLOR_RED); + black = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK); + CollaborationConnection.getConnection().registerEventHandler(this); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView#dispose + * () + */ + @Override + public void dispose() { + CollaborationConnection conn = CollaborationConnection.getConnection(); + if (conn != null) { + conn.unregisterEventHandler(this); + } + super.dispose(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * populateSashForm(org.eclipse.swt.custom.SashForm) + */ + @Override + protected void populateSashForm(SashForm sashForm) { + super.populateSashForm(sashForm); + sashForm.setWeights(new int[] { 20, 5 }); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * setMessageLabel(org.eclipse.swt.widgets.Label) + */ + @Override + protected void setMessageLabel(Composite comp) { + // no message needed as there is no subject and we know that it is + // private based on the fact that there are no participants + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView#sendMessage + * () + */ + @Override + public void sendMessage() { + String message = getComposedMessage(); + if (message.length() > 0) { + try { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + appendMessage(connection.getUser(), System.currentTimeMillis(), + message, null); + if (online) { + IPeerToPeer p2p = (IPeerToPeer) connection + .getPeerToPeerSession(); + p2p.sendPeerToPeer(peer, message); + } else { + StringBuilder builder = new StringBuilder(); + builder.append("Unable to send message. User is not online."); + sendErrorMessage(builder); + } + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to send message to " + peer.getName(), e); + } + } + } + + @Override + protected void styleAndAppendText(StringBuilder sb, int offset, + String name, UserId userId, String subject, List ranges) { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection == null) { + return; + } + Color color = null; + if (userId == null) { + color = black; + } else if (!userId.equals(connection.getUser())) { + color = chatterColor; + } else { + color = userColor; + } + styleAndAppendText(sb, offset, name, userId, ranges, color); + }; + + @Override + public void styleAndAppendText(StringBuilder sb, int offset, String name, + UserId userId, List ranges, Color color) { + StyleRange range = new StyleRange(messagesText.getCharCount(), offset, + color, null, SWT.NORMAL); + ranges.add(range); + if (userId != null) { + range = new StyleRange(messagesText.getCharCount() + offset, + name.length() + 1, color, null, SWT.BOLD); + } else { + range = new StyleRange(messagesText.getCharCount() + offset, + sb.length() - offset, color, null, SWT.BOLD); + } + ranges.add(range); + messagesText.append(sb.toString()); + for (StyleRange newRange : ranges) { + messagesText.setStyleRange(newRange); + } + messagesText.setTopIndex(messagesText.getLineCount() - 1); + } + + @Override + protected String getSessionImageName() { + return PEER_TO_PEER_IMAGE_NAME; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * getSessionName() + */ + @Override + protected String getSessionName() { + if (peer == null) { + return getViewSite().getSecondaryId(); + } else if (peer instanceof IUser) { + return CollaborationConnection.getConnection().getContactsManager() + .getDisplayName((IUser) peer); + } else { + return peer.getFQName(); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * getMessageArchive() + */ + @Override + protected SessionMsgArchive createMessageArchive() { + UserId me = CollaborationConnection.getConnection().getUser(); + return new SessionMsgArchive(me.getHost(), me.getName(), peer.getName()); + } + + public void setPeer(IQualifiedID peer) { + this.peer = peer; + setPartName(getSessionName()); + initMessageArchive(); + } + + public IQualifiedID getPeer() { + return peer; + } + + @Subscribe + public void handleModifiedPresence(IRosterEntry entry) { + UserId id = IDConverter.convertFrom(entry.getUser()); + if (id.equals(peer)) { + if (entry.getPresence().getType() == Type.UNAVAILABLE) { + online = false; + } else { + online = true; + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * initComponents(org.eclipse.swt.widgets.Composite) + */ + @Override + protected void initComponents(Composite parent) { + super.initComponents(parent); + + // unfortunately this code cannot be a part of createToolbarButton + // because I cannot instantiate the ACI until after the messagesText + // widget is instantiated which happens in initComponents + IContributionItem printAction = new PrintLogActionContributionItem(this); + ToolBarManager mgr = (ToolBarManager) getViewSite().getActionBars() + .getToolBarManager(); + mgr.insert(mgr.getSize() - 1, printAction); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.IPrintableView#getStyledText + * () + */ + @Override + public StyledText getStyledText() { + return messagesText; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.IPrintableView#getHeaderText + * () + */ + @Override + public String getHeaderText() { + DateFormat dateFormatter = new SimpleDateFormat("dd MMM yyyy"); + return "Conversation session with user " + getSessionName() + + ", Date: " + + dateFormatter.format(msgArchive.getCreationTime()); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SearchComposite.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SearchComposite.java new file mode 100644 index 0000000000..eeab32eb12 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SearchComposite.java @@ -0,0 +1,454 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +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.Display; +import org.eclipse.swt.widgets.Text; + +/** + * Simple search composite control for a text based composite.. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 31, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public class SearchComposite extends Composite { + + final Color HIGHLIGHT_COLOR = Display.getCurrent().getSystemColor( + SWT.COLOR_YELLOW); + + private StringBuilder text; + + private Button caseSensitive; + + private String textToSearch; + + private List results; + + private int index = -1; + + private ISearchText searchText; + + private KeyListener searchKeyListener; + + private Text searchBox; + + private Button bck; + + private Button fwd; + + private List originalStyles; + + // need this to update matches even when the user is not currently on the + // chat tab + private boolean visible; + + public class DefaultSearchText implements ISearchText { + private StyledText searchView; + + public DefaultSearchText(StyledText searchView) { + this.searchView = searchView; + } + + @Override + public void select(int start, int end) { + this.searchView.setSelectionRange(start, end - start); + } + + @Override + public void reachedLast() { + // go to first + if (index == results.size()) { + index = 0; + } + } + + @Override + public void reachedFirst() { + // go to last + while (index == 0) { + index = results.size() - 1; + } + } + + @Override + public StyledText getStyledText() { + return searchView; + } + + } + + private static final Comparator startComparator = new Comparator() { + /* + * return less than one; zero; and greater than one if o2 start is + * before; equal to; or after o1 start. + */ + @Override + public int compare(StyleRange o1, StyleRange o2) { + return o1.start - o2.start; + } + }; + + /** + * @param parent + * @param style + */ + public SearchComposite(Composite parent, int style) { + super(parent, style); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false); + this.setLayout(new GridLayout(1, false)); + this.setLayoutData(gd); + + results = new ArrayList(); + originalStyles = new ArrayList(); + searchBox = new Text(this, SWT.RESIZE | SWT.BORDER); + searchBox + .setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + gd = new GridData(SWT.FILL, SWT.FILL, true, false); + searchBox.setLayoutData(gd); + + Composite searchControls = new Composite(this, SWT.NONE); + searchControls.setLayout(new GridLayout(5, false)); + setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); + + Button first = new Button(searchControls, SWT.PUSH); + first.setText("<<"); + first.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + first.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + index = 0; + doSearch(); + } + }); + + bck = new Button(searchControls, SWT.PUSH); + bck.setText("<"); + bck.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + bck.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + decrementIndex(); + doSearch(); + } + }); + + fwd = new Button(searchControls, SWT.PUSH); + fwd.setText(">"); + fwd.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + fwd.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + incrementIndex(); + doSearch(); + } + }); + + Button last = new Button(searchControls, SWT.PUSH); + last.setText(">>"); + last.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); + last.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + index = results.size() - 1; + doSearch(); + } + }); + + caseSensitive = new Button(searchControls, SWT.CHECK); + caseSensitive.setText("Case"); + caseSensitive.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, + false)); + + searchKeyListener = new KeyListener() { + + private boolean shiftPressed = false; + + /** + * Check for search "text" inputs. + * + * @see org.eclipse.swt.events.KeyListener#keyReleased(org.eclipse.swt.events.KeyEvent) + */ + @Override + public void keyReleased(KeyEvent e) { + if (textToSearch == null + || textToSearch.equals(searchBox.getText()) == false) { + textToSearch = searchBox.getText(); + updateMatches(); + } + + if (e.keyCode == SWT.SHIFT) { + shiftPressed = false; + } + } + + /** + * Check for search "movement" commands. + * + * @see org.eclipse.swt.events.KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent) + */ + @Override + public void keyPressed(KeyEvent e) { + if (e.keyCode == SWT.KEYPAD_CR || e.keyCode == SWT.CR) { + if (index < 0) { + index = 0; + } else { + incrementIndex(); + } + nextSearchMatch(); + } else if (e.keyCode == SWT.SHIFT) { + shiftPressed = true; + } else { + searchBox.setFocus(); + } + } + }; + + this.addKeyListener(searchKeyListener); + searchBox.addKeyListener(searchKeyListener); + bck.addKeyListener(searchKeyListener); + fwd.addKeyListener(searchKeyListener); + caseSensitive.addKeyListener(searchKeyListener); + + caseSensitive.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateMatches(); + } + }); + } + + private void incrementIndex() { + index++; + if (index >= results.size()) { + index = 0; + } + } + + private void decrementIndex() { + index--; + if (index < 0) { + index = results.size() - 1; + } + } + + private void doSearch() { + if (textToSearch == null + || textToSearch.equals(searchBox.getText()) == false) { + textToSearch = searchBox.getText(); + updateMatches(); + } + nextSearchMatch(); + } + + public boolean search(KeyEvent e) { + boolean result = false; + if (((e.stateMask & SWT.CTRL) == SWT.CTRL)) { + if (e.keyCode == 'f') { + hide(false); + updateMatches(); + searchBox.setFocus(); + } + } else if (e.keyCode == SWT.ESC) { + hide(true); + redraw(); + result = true; + } + return result; + } + + public void hide(boolean isHidden) { + ((GridData) getLayoutData()).exclude = isHidden; + setVisible(!isHidden); + visible = !isHidden; + if (searchText != null) { + removeHighlights(); + } + getParent().layout(); + } + + private void removeHighlights() { + searchText.getStyledText().setStyleRanges( + originalStyles.toArray(new StyleRange[0])); + } + + /** + * increment/decrement to next match. if at end of matches, increment to + * next/previous leaf. + * + * @param tree2 + */ + protected void nextSearchMatch() { + if (results == null || results.isEmpty()) { + return; + } + MatchResult current = results.get(index); + searchText.select(current.start(), current.end()); + } + + private void updateMatches() { + int patternFlags = Pattern.LITERAL + | (caseSensitive.getSelection() ? 0 : Pattern.CASE_INSENSITIVE); + + results.clear(); + + if (textToSearch != null && textToSearch.isEmpty() == false) { + Pattern pattern = Pattern.compile(textToSearch, patternFlags); + Matcher matcher = pattern.matcher(text); + + while (matcher.find()) { + results.add(matcher.toMatchResult()); + } + } + + removeHighlights(); + if (results.size() > 0) { + List highlights = new ArrayList(); + + highlights.addAll(Arrays.asList(searchText.getStyledText() + .getStyleRanges())); + StyledText text = searchText.getStyledText(); + // for each match + for (MatchResult result : results) { + // grab the style ranges within that match + StyleRange[] ranges = text.getStyleRanges(result.start(), + result.end() - result.start()); + // create a single huge range for the entire match that is + // highlighted + StyleRange range = new StyleRange(result.start(), result.end() + - result.start(), null, HIGHLIGHT_COLOR); + List finalRanges = new ArrayList(); + finalRanges.add(range); + // loop through the style ranges + for (StyleRange rng : ranges) { + // add a style range according to each one, that is + // highlighted + if (finalRanges.get(0).start == rng.start + && finalRanges.get(0).length == rng.length) { + finalRanges.remove(0); + } + finalRanges.add(new StyleRange(rng.start, rng.length, + rng.foreground, HIGHLIGHT_COLOR, rng.fontStyle)); + } + text.replaceStyleRanges(result.start(), + result.end() - result.start(), + finalRanges.toArray(new StyleRange[0])); + } + } + } + + private void setOriginalStyles(StyledText styledText) { + originalStyles.clear(); + originalStyles.addAll(Arrays.asList(styledText.getStyleRanges())); + } + + /** + * @param searchText + * the SearchText to set + */ + public void setSearchText(ISearchText searchText) { + this.searchText = searchText; + StyledText styledText = searchText.getStyledText(); + setOriginalStyles(styledText); + if (isVisible()) { + updateMatches(); + } + } + + /** + * @param styledText + */ + public void setSearchText(StyledText styledText) { + setText(styledText.getText()); + setSearchText(new DefaultSearchText(styledText)); + } + + /** + * @return the text + */ + public String getText() { + return text.toString(); + } + + /** + * @param text + * the text to set + */ + private void setText(String text) { + if (this.text == null) { + this.text = new StringBuilder(); + } + this.text.append(text); + } + + /** + * @return the searchKeyListener + */ + public KeyListener getSearchKeyListener() { + return searchKeyListener; + } + + public void appendText(String newText) { + originalStyles.addAll(Arrays.asList(searchText.getStyledText() + .getStyleRanges(this.text.length(), newText.length()))); + this.text.append(newText); + if (visible) { + updateMatches(); + } + } + + public void toggleVisibility() { + hide(isVisible()); + if (isVisible()) { + updateMatches(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java new file mode 100644 index 0000000000..315ec47e6b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionFeedView.java @@ -0,0 +1,438 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation; +import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation.SiteConfig; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.SiteColorInformation; +import com.raytheon.uf.viz.collaboration.ui.SiteColorInformation.SiteColor; +import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager; +import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants; + +/** + * Built for the session in which everyone joins + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 7, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ + +public class SessionFeedView extends SessionView { + + public static final String ID = "com.raytheon.uf.viz.collaboration.SessionFeedView"; + + private Action colorChangeAction; + + private Action autoJoinAction; + + private Action userAddSiteAction; + + private Action userRemoveSiteAction; + + private List enabledSites; + + private List userEnabledSites; + + private List colors; + + /** + * + */ + public SessionFeedView() { + super(); + String actingSite = CollaborationConnection.getConnection() + .getPresence().getProperties() + .get(SiteConfigInformation.SITE_NAME).toString(); + enabledSites = SiteConfigurationManager.getSubscribeList(actingSite); + userEnabledSites = SiteConfigurationManager.getUserSubscribeList(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#initComponents + * (org.eclipse.swt.widgets.Composite) + */ + @Override + protected void initComponents(Composite parent) { + super.initComponents(parent); + colors = SiteConfigurationManager.getSiteColors(); + if (colors != null) { + for (IUser user : session.getVenue().getParticipants()) { + setColorForSite(user); + } + } else { + colors = new ArrayList(); + } + usersTable.refresh(); + } + + @Subscribe + public void refreshBlockList(SubscribeList list) { + enabledSites = list.getEnabledSites(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#createActions() + */ + @Override + protected void createActions() { + super.createActions(); + + colorChangeAction = new Action("Change Site Color...") { + @Override + public void run() { + ColorDialog dlg = new ColorDialog(Display.getCurrent() + .getActiveShell()); + RGB rgb = dlg.open(); + // get the selected entry so we know what site to change the + // color for + String site = getSelectedSite(); + + replaceSiteColor(site.toString(), rgb); + // loop through all the entries in the list so we can set the + // color for all sites corresponding to "selectedSite" + if (site != null) { + for (IUser user : session.getVenue().getParticipants()) { + setColorForSite(user); + } + } + + usersTable.refresh(); + } + }; + + autoJoinAction = new Action(CollabPrefConstants.AUTO_JOIN, SWT.TOGGLE) { + @Override + public void run() { + Activator + .getDefault() + .getPreferenceStore() + .setValue(CollabPrefConstants.AUTO_JOIN, + autoJoinAction.isChecked()); + }; + }; + + autoJoinAction.setChecked(Activator.getDefault().getPreferenceStore() + .getBoolean(CollabPrefConstants.AUTO_JOIN)); + Activator.getDefault().getPreferenceStore() + .addPropertyChangeListener(new IPropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent event) { + autoJoinAction.setChecked(Activator.getDefault() + .getPreferenceStore() + .getBoolean(CollabPrefConstants.AUTO_JOIN)); + } + }); + + userAddSiteAction = new Action("Subscribe") { + public void run() { + userEnabledSites.add(getSelectedSite()); + }; + }; + + userRemoveSiteAction = new Action("Unsubscribe") { + public void run() { + userEnabledSites.remove(getSelectedSite()); + } + }; + + MenuManager manager = (MenuManager) getViewSite().getActionBars() + .getMenuManager(); + manager.add(autoJoinAction); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#fillContextMenu + * (org.eclipse.jface.action.IMenuManager) + */ + @Override + protected void fillContextMenu(IMenuManager manager) { + super.fillContextMenu(manager); + manager.add(colorChangeAction); + String site = getSelectedSite(); + if (userEnabledSites.contains(site) == false + && enabledSites.contains(site) == false) { + userAddSiteAction.setText("Subscribe to " + getSelectedSite()); + manager.add(userAddSiteAction); + } else if (enabledSites.contains(site) == false + && userEnabledSites.contains(site)) { + userRemoveSiteAction.setText("Unsubscribe from " + + getSelectedSite()); + manager.add(userRemoveSiteAction); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#setParticipantValues + * (com.raytheon.uf.viz.collaboration.ui.session.ParticipantsLabelProvider) + */ + @Override + protected void setParticipantValues(ParticipantsLabelProvider labelProvider) { + super.setParticipantValues(labelProvider); + labelProvider.setEnabledSites(enabledSites); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#handleMessage + * (com.raytheon.uf.viz.collaboration.comm.identity.IMessage) + */ + @Override + public void handleMessage(IMessage message) { + final IMessage msg = message; + boolean isHistory = isHistory(msg); + + // so not to have delay, going to handle messages from yourself + // separately + if (isSelf(msg, isHistory)) { + return; + } + + Object site = null; + if (isHistory) { + site = msg.getSubject(); + } else if (msg.getFrom() instanceof IUser) { + IPresence presence = session.getVenue().getPresence( + (IUser) msg.getFrom()); + site = presence.getProperties() + .get(SiteConfigInformation.SITE_NAME); + } + + // should we append? + if (site == null || enabledSites.contains(site) + || userEnabledSites.contains(site)) { + appendMessage(msg); + } + } + + @Override + protected void styleAndAppendText(StringBuilder sb, int offset, + String name, UserId userId, String subject, List ranges) { + if (subject != null) { + setColorForSite(userId, subject); + } + super.styleAndAppendText(sb, offset, name, userId, subject, ranges); + } + + /** + * Get the acting site based on the first user that is selected out of the + * list + * + * @return + */ + private String getSelectedSite() { + IStructuredSelection selection = (IStructuredSelection) usersTable + .getSelection(); + IUser selectedEntry = (IUser) selection.getFirstElement(); + IPresence pres = session.getVenue().getPresence(selectedEntry); + Object selectedSite = pres.getProperties().get( + SiteConfigInformation.SITE_NAME); + return selectedSite.toString(); + } + + /** + * Takes an IRosterEntry and sets their color in the SessionColorManager for + * the site that they belong to, calls into + * setColorForSite(UserId,IPresence) + * + * @param user + */ + private void setColorForSite(IUser user) { + UserId id = IDConverter.convertFrom(user); + IPresence presence = session.getVenue().getPresence(user); + setColorForSite(id, presence); + } + + /** + * Does the work for setting the color for each user that belongs to a site + * + * @param id + * @param presence + */ + private void setColorForSite(UserId id, IPresence presence) { + if (presence == null) { + return; + } + Object site = presence.getProperties().get( + SiteConfigInformation.SITE_NAME); + if (site != null) { + setColorForSite(id, site.toString()); + } + } + + private void setColorForSite(UserId id, String site) { + SiteColor siteColor = new SiteColor(); + siteColor.setSite(site.toString()); + int index = colors.indexOf(siteColor); + if (index >= 0) { + SiteColor actualColor = colors.get(index); + colorManager.setColorForUser(id, actualColor.getColor()); + } + } + + /** + * Removes the color from the map if the site exists in the list + * + * @param site + * @param rgb + */ + private void replaceSiteColor(String site, RGB rgb) { + // now that the users have their color set, we need to add + // to the list that has the site color information + SiteColor color = new SiteColor(); + color.setSite(site); + color.setColor(rgb); + boolean exists = false; + for (SiteColor col : SessionFeedView.this.colors) { + if (col.getSite().equals(site)) { + exists = true; + } + } + if (exists) { + SessionFeedView.this.colors.remove(color); + } + SessionFeedView.this.colors.add(color); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#participantArrived + * (com.raytheon.uf.viz.collaboration.comm.provider.user.UserId) + */ + @Override + protected void participantArrived(UserId participant) { + setColorForSite(participant); + if (session != null && session.getVenue() != null) { + Object siteOb = session.getVenue().getPresence(participant) + .getProperties().get(SiteConfigInformation.SITE_NAME); + String site = ""; + if (siteOb != null) { + site = siteOb.toString(); + } + // only show sites you care about, or empty site + if ("".equals(site) || enabledSites.contains(site) + || userEnabledSites.contains(site)) { + super.participantArrived(participant); + } else { + usersTable.setInput(session.getVenue().getParticipants()); + usersTable.refresh(); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.SessionView#participantDeparted + * (com.raytheon.uf.viz.collaboration.comm.provider.user.UserId) + */ + @Override + protected void participantDeparted(UserId participant) { + String site = session.getVenue().getPresence(participant) + .getProperties().get(SiteConfigInformation.SITE_NAME) + .toString(); + // only show sites you care about + if (enabledSites.contains(site) || userEnabledSites.contains(site)) { + super.participantDeparted(participant); + } else { + usersTable.setInput(session.getVenue().getParticipants()); + usersTable.refresh(); + } + } + + @Override + protected void participantPresenceUpdated(UserId participant, + IPresence presence) { + setColorForSite(participant, presence); + super.participantPresenceUpdated(participant, presence); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.SessionView#dispose() + */ + @Override + public void dispose() { + super.dispose(); + SiteColorInformation information = new SiteColorInformation(); + information.setColors(this.colors); + SiteConfigurationManager.writeSiteColorInformation(information); + + // write out the user enabled sites information to a file + SiteConfigInformation userInformation = new SiteConfigInformation(); + List sites = new ArrayList(); + SiteConfig config = new SiteConfig(); + config.setSubscribedSites(userEnabledSites.toArray(new String[0])); + sites.add(config); + userInformation.setConfig(sites); + SiteConfigurationManager + .writeUserSiteConfigInformation(userInformation); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchive.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchive.java new file mode 100644 index 0000000000..9409e20f8b --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchive.java @@ -0,0 +1,131 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationLevel; +import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.ui.Activator; + +/** + * Message archiver for a collaboration session. Archives messages to + * Localization. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public class SessionMsgArchive { + + private static final String LOG_DIR = "collaboration" + + IPathManager.SEPARATOR + "logs"; + + private LocalizationFile logFile; + + private StringBuffer log; + + private Calendar creationTime; + + public SessionMsgArchive(String hostName, String userId, String sessionName) { + this.creationTime = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + String logFileName = new SimpleDateFormat("yyyy-MM-dd.hhmmss") + .format(this.creationTime.getTime()) + ".txt"; + + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext ctx = pm.getContext(LocalizationType.CAVE_STATIC, + LocalizationLevel.USER); + logFile = pm.getLocalizationFile(ctx, + getLogFilePath(hostName, userId, sessionName) + + IPathManager.SEPARATOR + logFileName); + log = new StringBuffer(); + } + + public static String getLogFilePath(String hostName, String userId, + String sessionName) { + return LOG_DIR + + IPathManager.SEPARATOR + + hostName + + IPathManager.SEPARATOR + + userId + + (sessionName == null ? "" : IPathManager.SEPARATOR + + sessionName); + } + + public static LocalizationContext getArchiveContext() { + IPathManager pm = PathManagerFactory.getPathManager(); + return pm.getContext(LocalizationType.CAVE_STATIC, + LocalizationLevel.USER); + } + + public static LocalizationFile getArchiveDir(String logFilePath) { + IPathManager pm = PathManagerFactory.getPathManager(); + return pm.getLocalizationFile(getArchiveContext(), logFilePath); + } + + public static LocalizationFile getArchiveDir(String hostName, + String userId, String sessionName) { + IPathManager pm = PathManagerFactory.getPathManager(); + return pm.getLocalizationFile(getArchiveContext(), + getLogFilePath(hostName, userId, sessionName)); + } + + public void close() { + // Write log contents to logFile + try { + logFile.write(log.toString().getBytes()); + } catch (LocalizationException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error writing log file: " + e.getLocalizedMessage(), e); + } + } + + public void archive(String string) { + log.append(string); + } + + public Date getCreationTime() { + return creationTime.getTime(); + } + + public void archiveLine(String string) { + log.append("\n").append(string); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveBrowser.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveBrowser.java new file mode 100644 index 0000000000..514af06d44 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveBrowser.java @@ -0,0 +1,414 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +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.Label; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeItem; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationContext; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; + +/** + * Browse, view, and search messages in the archive. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 22, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public class SessionMsgArchiveBrowser extends Composite implements ISearchText { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(SessionMsgArchiveBrowser.class); + + final Color INACTIVE_COLOR = Display.getCurrent().getSystemColor( + SWT.COLOR_TITLE_INACTIVE_FOREGROUND); + + final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd.hhmmss"); + + final SimpleDateFormat newSdf = new SimpleDateFormat( + "EEE d MMM yyyy HH:mm:ss z"); + + private StyledText logView; + + private Label logName; + + private List leaves; + + private ListIterator leafIter; + + private Tree tree; + + private SearchComposite searchComp; + + private String browserName; + + private Object logDir; + + /** + * @param parent + * @param style + */ + public SessionMsgArchiveBrowser(Composite parent, int style) { + super(parent, style); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + this.setLayout(new GridLayout(1, true)); + this.setLayoutData(gd); + init(); + } + + /** + * @param parent + * @param style + */ + public SessionMsgArchiveBrowser(Composite parent, int style, + LocalizationFile logDir) { + this(parent, style); + setDir(logDir); + } + + public void setDir(LocalizationFile logDir) { + + if (this.logDir != null && this.logDir.equals(logDir)) { + return; + } + + try { + if (logDir == null) { + UserId user = CollaborationConnection.getConnection().getUser(); + logDir = SessionMsgArchive.getArchiveDir(user.getHost(), + user.getName(), null); + } + this.logDir = logDir; + setBrowserName(logDir); + populateTree(tree, leaves, logDir); + leafIter = leaves.listIterator(); + } catch (ParseException e) { + statusHandler + .error("Unable to parse log directory tree to produce collaboration log view", + e); + } + } + + protected void init() { + SashForm mainForm = new SashForm(this, SWT.HORIZONTAL); + mainForm.setLayout(new GridLayout(2, false)); + + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.widthHint = 800; + gd.heightHint = 600; + mainForm.setLayoutData(gd); + + Composite childBarComp = new Composite(mainForm, SWT.NONE); + childBarComp.setLayout(new GridLayout(1, false)); + childBarComp + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + tree = new Tree(childBarComp, SWT.BORDER); + leaves = new ArrayList(); + leafIter = leaves.listIterator(); + + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.heightHint = 300; + gd.widthHint = 400; + tree.setLayoutData(gd); + + Composite logViewPart = new Composite(mainForm, SWT.NONE); + logViewPart.setLayout(new GridLayout(1, false)); + logViewPart.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true)); + + Composite logHeaderPart = new Composite(logViewPart, SWT.NONE); + logHeaderPart.setLayout(new GridLayout(1, false)); + logHeaderPart.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, + false)); + + logName = new Label(logHeaderPart, SWT.READ_ONLY); + gd = new GridData(SWT.LEFT, SWT.CENTER, false, false); + gd.widthHint = 200; + logName.setLayoutData(gd); + + logView = new StyledText(logViewPart, SWT.V_SCROLL | SWT.H_SCROLL + | SWT.BORDER | SWT.READ_ONLY); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + logView.setLayoutData(gd); + logView.setEditable(false); + + searchComp = new SearchComposite(logViewPart, SWT.BORDER); + searchComp.setSearchText(this); + searchComp.hide(true); + + tree.addKeyListener(searchComp.getSearchKeyListener()); + logView.addKeyListener(searchComp.getSearchKeyListener()); + + tree.addSelectionListener(new SelectionListener() { + @Override + public void widgetSelected(SelectionEvent event) { + Object data = event.item.getData(); + if (data != null) { + TreeItem tItem = (TreeItem) event.item; + setLogView(tItem); + } + } + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + mainForm.setWeights(new int[] { 30, 70 }); + mainForm.setVisible(true); + } + + /** + * Set the current leaf displayed in the log viewer. If search is on, then + * + * @param tItem + */ + private void setLogView(TreeItem tItem) { + Object data = tItem.getData(); + + if (data != null) { + tItem.setExpanded(true); + tItem.getParent().setSelection(tItem); + + try { + LocalizationFile lFile = (LocalizationFile) tItem.getData(); + File file = lFile.getFile(true); + + if (file != null && file.exists()) { + BufferedReader reader = null; + try { + FileReader fReader = new FileReader(file); + + reader = new BufferedReader(fReader); + char[] cbuf = new char[1024]; + StringBuilder sb = new StringBuilder(); + while (reader.read(cbuf) != -1) { + sb.append(cbuf); + } + logName.setText(tItem.getText()); + logView.setText(sb.toString()); + searchComp.setSearchText(logView); + } finally { + if (reader != null) { + reader.close(); + } + } + } + } catch (LocalizationException e) { + statusHandler + .error("Unable to retrieve collaboration log file from localization", + e); + } catch (FileNotFoundException e) { + statusHandler + .error("Unable to find collaboration log file in localization", + e); + } catch (IOException e) { + statusHandler + .error("Unable to read collaboration log file from localization", + e); + } + } + } + + private void populateTree(Tree tree, List leaves, + LocalizationFile logDir) throws ParseException { + + tree.clearAll(true); + leaves.clear(); + + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationContext[] contexts = pm.getLocalSearchHierarchy(logDir + .getContext().getLocalizationType()); + LocalizationFile[] files = pm.listFiles(contexts, logDir.getName(), + null, true, true); // Win32 + + Map itemMap = new HashMap( + files.length); + for (final LocalizationFile lFile : files) { + String name = lFile.getName().replaceFirst( + logDir.getName() + File.separator, ""); + String[] parts = name.split(File.separator); + String parentPath = ""; + for (int i = 0; i < parts.length; ++i) { + String part = parts[i]; + TreeItem parentItem = itemMap.get(parentPath); + + parentPath += File.separator + part; + TreeItem item = itemMap.get(parentPath); + if (item == null) { + if (parentItem == null) { + item = new TreeItem(tree, SWT.NONE); + } else { + item = new TreeItem(parentItem, SWT.NONE); + } + + boolean isLeaf = (i == parts.length - 1); + + if (isLeaf) { + item.setData(lFile); + + String datePart = part.substring(0, + part.lastIndexOf(".")); + Date d = sdf.parse(datePart); + item.setText(newSdf.format(d)); + leaves.add(item); + } else { + item.setForeground(INACTIVE_COLOR); + item.setText(part); + } + item.setExpanded(!isLeaf); + itemMap.put(parentPath, item); + } + } + } + } + + @Override + public void select(int start, int end) { + logView.setSelection(start, end); + } + + /** + * searching forward, reached last item. + */ + @Override + public void reachedLast() { + TreeItem selected = null; + TreeItem[] arr = tree.getSelection(); + + if (arr.length > 0) { + selected = arr[0]; + } else { + selected = leaves.get(0); + } + if (leafIter.hasNext()) { + selected = leafIter.next(); + } else { + leafIter = leaves.listIterator(); + selected = leafIter.next(); + } + setLogView(selected); + } + + /** + * searching backward, reached first item. + */ + @Override + public void reachedFirst() { + TreeItem selected = null; + TreeItem[] arr = tree.getSelection(); + + if (arr.length > 0) { + selected = arr[0]; + } else { + selected = leaves.get(0); + } + if (leafIter.hasPrevious()) { + selected = leafIter.previous(); + } else { + int index = leaves.size(); + leafIter = leaves.listIterator(index); + selected = leafIter.previous(); + } + setLogView(selected); + } + + /** + * @return the browserName + */ + public String getBrowserName() { + return browserName; + } + + /** + * @param logDir + * the logDir that defines the browserName + */ + private void setBrowserName(LocalizationFile logDir) { + String name = logDir.getName(); + String[] parts = name.split(File.separator); + + if (parts.length > 0) { + String lastPart = parts[parts.length - 1]; + + if (lastPart == null || lastPart.isEmpty()) { + if (parts.length > 1) { + lastPart = parts[parts.length - 2]; + } + } + this.browserName = "Log: " + lastPart; + } + } + + @Override + public StyledText getStyledText() { + return logView; + } + + public String getLogDate() { + return logName.getText(); + } + + public void toggleSearch() { + searchComp.toggleVisibility(); + } + +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveDialog.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveDialog.java new file mode 100644 index 0000000000..f960353746 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveDialog.java @@ -0,0 +1,88 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.common.localization.LocalizationFile; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 22, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public class SessionMsgArchiveDialog extends Dialog { + + private Shell shell; + + /** + * @param parent + */ + public SessionMsgArchiveDialog(Shell parent) { + super(parent); + } + + /** + * @param parent + * @param style + */ + public SessionMsgArchiveDialog(Shell parent, int style) { + super(parent, style); + } + + public void open(LocalizationFile logDir) { + Shell parent = getParent(); + + shell = new Shell(parent.getDisplay(), SWT.TITLE | SWT.RESIZE); + shell.setText(getText()); + shell.setLayout(new GridLayout(1, false)); + + SessionMsgArchiveBrowser smab = new SessionMsgArchiveBrowser(shell, + SWT.NONE, logDir); + + shell.pack(); + shell.open(); + + // Wait until the shell is disposed. + Display display = parent.getDisplay(); + while (!shell.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveView.java new file mode 100644 index 0000000000..78f427e80a --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionMsgArchiveView.java @@ -0,0 +1,118 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.viz.collaboration.ui.Activator; +import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.viz.ui.views.CaveFloatingView; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 22, 2012            bgonzale     Initial creation
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public class SessionMsgArchiveView extends CaveFloatingView implements + IPrintableView { + + private SessionMsgArchiveBrowser browser; + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + String secondaryId = getViewSite().getSecondaryId(); + LocalizationFile logDir = SessionMsgArchive.getArchiveDir(secondaryId); + + browser = new SessionMsgArchiveBrowser(parent, SWT.NONE); + browser.setDir(logDir); + + setPartName(browser.getBrowserName()); + parent.setLayout(new GridLayout(1, false)); + parent.layout(); + + // unfortunately this code cannot be a part of createToolbarButton + // because I cannot instantiate the ACI until after the StyledText + // control in SessionMsgArchiveBrowser is instantiated which happens + // above + IContributionItem printAction = new PrintLogActionContributionItem(this); + ToolBarManager mgr = (ToolBarManager) getViewSite().getActionBars() + .getToolBarManager(); + mgr.add(printAction); + + Action searchAction = new Action("Search") { + @Override + public void run() { + browser.toggleSearch(); + } + }; + searchAction.setImageDescriptor(IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), "find.gif")); + mgr.add(searchAction); + } + + @Override + public void setFocus() { + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.IPrintableView#getStyledText + * () + */ + @Override + public StyledText getStyledText() { + return browser.getStyledText(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.IPrintableView#getHeaderText + * () + */ + @Override + public String getHeaderText() { + return "Conversation log from " + browser.getLogDate(); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java new file mode 100644 index 0000000000..ccebb4c687 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SessionView.java @@ -0,0 +1,735 @@ +package com.raytheon.uf.viz.collaboration.ui.session; + +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.eclipse.ecf.core.user.IUser; +import org.eclipse.ecf.presence.IPresence; +import org.eclipse.ecf.presence.roster.IRosterEntry; +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IContributionItem; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.ToolBarManager; +import org.eclipse.jface.viewers.ArrayContentProvider; +import org.eclipse.jface.viewers.ColumnViewerToolTipSupport; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.jface.window.ToolTip; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.CLabel; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.MouseTrackAdapter; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +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.Label; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.PlatformUI; + +import com.google.common.eventbus.Subscribe; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException; +import com.raytheon.uf.viz.collaboration.comm.identity.IMessage; +import com.raytheon.uf.viz.collaboration.comm.identity.ISession; +import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession; +import com.raytheon.uf.viz.collaboration.comm.identity.event.IVenueParticipantEvent; +import com.raytheon.uf.viz.collaboration.comm.identity.event.ParticipantEventType; +import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenueInfo; +import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent; +import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection; +import com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession; +import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId; +import com.raytheon.uf.viz.collaboration.display.data.SessionColorManager; +import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.viz.ui.views.CaveWorkbenchPageManager; + +/** + * The ViewPart of a text only room, contains methods that are used by the + * shared display rooms and the feed room + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 1, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class SessionView extends AbstractSessionView implements IPrintableView { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(SessionView.class); + + private static final String SESSION_IMAGE_NAME = "chats.gif"; + + public static final String ID = "com.raytheon.uf.viz.collaboration.SessionView"; + + protected TableViewer usersTable; + + protected CLabel participantsLabel; + + protected String sessionId; + + protected IVenueSession session; + + private Image downArrow; + + private Image rightArrow; + + private Image highlightedRightArrow; + + private Image highlightedDownArrow; + + protected Action chatAction; + + protected SessionColorManager colorManager; + + protected Map mappedColors; + + public SessionView() { + super(); + } + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + createActions(); + createContextMenu(); + mappedColors = new HashMap(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * initComponents(org.eclipse.swt.widgets.Composite) + */ + @Override + protected void initComponents(Composite parent) { + initColorManager(); + super.initComponents(parent); + + // unfortunately this code cannot be a part of createToolbarButton + // because I cannot instantiate the ACI until after the messagesText + // widget is instantiated which happens in initComponents + IContributionItem printAction = new PrintLogActionContributionItem(this); + ToolBarManager mgr = (ToolBarManager) getViewSite().getActionBars() + .getToolBarManager(); + mgr.add(printAction); + } + + @Override + protected void populateSashForm(SashForm sashForm) { + createArrows(); + createUsersComp(sashForm); + super.populateSashForm(sashForm); + sashForm.setWeights(new int[] { 1, 20, 5 }); + } + + protected void createActions() { + chatAction = new Action("Chat") { + @Override + public void run() { + try { + ISession session = CollaborationConnection.getConnection() + .getPeerToPeerSession(); + CaveWorkbenchPageManager.getActiveInstance().showView( + PeerToPeerView.ID, session.getSessionId(), + IWorkbenchPage.VIEW_ACTIVATE); + } catch (PartInitException e) { + statusHandler.handle(Priority.PROBLEM, + "Unable to open chat", e); + } catch (CollaborationException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + }; + } + + /** + * + */ + private void createContextMenu() { + MenuManager menuManager = new MenuManager(); + menuManager.setRemoveAllWhenShown(true); + menuManager.addMenuListener(new IMenuListener() { + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse + * .jface.action.IMenuManager) + */ + @Override + public void menuAboutToShow(IMenuManager manager) { + fillContextMenu(manager); + } + }); + Menu menu = menuManager.createContextMenu(usersTable.getControl()); + usersTable.getControl().setMenu(menu); + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .getActivePart().getSite() + .registerContextMenu(menuManager, usersTable); + usersTable.getTable().setMenu(menu); + } + + protected void fillContextMenu(IMenuManager manager) { + } + + @Subscribe + public void handleMessage(IMessage message) { + final IMessage msg = message; + + boolean isHistory = isHistory(msg); + // so not to have delay, going to handle messages from yourself + // separately + // unless it is history, then you want to show them + if (isSelf(msg, isHistory)) { + return; + } + appendMessage(msg); + + } + + @Subscribe + public void updateUserAlias(UserId id) { + List entries = (List) usersTable.getInput(); + for (IRosterEntry entry : entries) { + UserId uid = (UserId) entry.getUser(); + if (uid.getFQName().equals(id.getFQName())) { + ((UserId) entry.getUser()).setName(id.getAlias()); + break; + } + } + usersTable.refresh(); + } + + protected void initColorManager() { + colorManager = new SessionColorManager(); + } + + protected void createUsersComp(final Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(1, false); + GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); + comp.setLayout(layout); + comp.setLayoutData(data); + + participantsLabel = new CLabel(comp, SWT.NONE); + layout = new GridLayout(1, false); + data = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + participantsLabel.setLayout(layout); + participantsLabel.setLayoutData(data); + participantsLabel.setText("Participants"); + participantsLabel.setImage(rightArrow); + participantsLabel.setToolTipText("Select to show participants..."); + + final Composite usersComp = new Composite(comp, SWT.NONE); + layout = new GridLayout(1, false); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + usersComp.setVisible(false); + layout.marginWidth = 0; + usersComp.setLayout(layout); + usersComp.setLayoutData(data); + + participantsLabel.addMouseTrackListener(new MouseTrackAdapter() { + @Override + public void mouseEnter(MouseEvent e) { + if (usersComp.getVisible()) { + participantsLabel.setImage(highlightedDownArrow); + } else { + participantsLabel.setImage(highlightedRightArrow); + } + } + + @Override + public void mouseExit(MouseEvent e) { + if (usersComp.getVisible()) { + participantsLabel.setImage(downArrow); + } else { + participantsLabel.setImage(rightArrow); + } + } + }); + participantsLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseDown(MouseEvent e) { + GridData data = ((GridData) usersComp.getLayoutData()); + data.exclude = !data.exclude; + usersComp.setVisible(!data.exclude); + + usersComp.layout(); + int[] weights = ((SashForm) parent).getWeights(); + if (!usersComp.getVisible()) { + int val = weights[0] + weights[1] + weights[2]; + val = (int) Math.ceil((val / 26.0)); + weights[1] = weights[0] + weights[1] - 1; + weights[0] = val; + participantsLabel.setImage(rightArrow); + participantsLabel + .setToolTipText("Select to show participants..."); + } else { + // fix this to make up for possible negative values TODO XXX + int val = usersComp.computeSize(SWT.DEFAULT, SWT.DEFAULT).y + + participantsLabel.getBounds().height; + double percentage = ((double) val) + / (double) parent.getSize().y; + // not greater than 50% of view when popping out + if (percentage > 0.5) { + percentage = 0.5; + } + int weight = weights[0] + weights[1] + weights[2]; + double tmp = weight * percentage; + weights[1] = (int) (weights[1] - tmp); + weights[0] = (int) (weights[0] + tmp); + participantsLabel.setImage(downArrow); + participantsLabel + .setToolTipText("Select to hide participants..."); + } + ((SashForm) parent).setWeights(weights); + parent.layout(); + } + }); + + usersTable = new TableViewer(usersComp, SWT.BORDER | SWT.SINGLE + | SWT.V_SCROLL | SWT.H_SCROLL); + layout = new GridLayout(1, false); + data = new GridData(SWT.FILL, SWT.FILL, true, true); + usersTable.getTable().setLayout(layout); + usersTable.getTable().setLayoutData(data); + + ParticipantsLabelProvider labelProvider = new ParticipantsLabelProvider(); + setParticipantValues(labelProvider); + usersTable.setContentProvider(ArrayContentProvider.getInstance()); + + usersTable.setLabelProvider(labelProvider); + usersTable.setSorter(new ViewerSorter() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + IUser c1 = (IUser) e1; + IUser c2 = (IUser) e1; + + return c1.getID().getName().compareTo(c2.getID().getName()); + } + }); + + ColumnViewerToolTipSupport.enableFor(usersTable, ToolTip.RECREATE); + if (session != null) { + usersTable.setInput(session.getVenue().getParticipants()); + } else { + // session was null, why this would happen we don't know but this + // will somewhat gracefully let the user know a problem occurred and + // will not let them do anything in this view + statusHandler.handle(Priority.PROBLEM, + "Session was null, which means a major problem occurred"); + participantsLabel.setEnabled(false); + participantsLabel.setForeground(Display.getCurrent() + .getSystemColor(SWT.COLOR_DARK_GRAY)); + comp.setEnabled(false); + } + ((GridData) usersComp.getLayoutData()).exclude = true; + } + + protected void setParticipantValues(ParticipantsLabelProvider labelProvider) { + labelProvider.setSessionId(sessionId); + labelProvider.setManager(colorManager); + } + + @Override + public void dispose() { + // dispose of the images first + disposeArrow(highlightedDownArrow); + disposeArrow(highlightedRightArrow); + disposeArrow(downArrow); + disposeArrow(rightArrow); + + if (mappedColors != null) { + for (Color col : mappedColors.values()) { + col.dispose(); + } + mappedColors.clear(); + } + if (colorManager != null) { + colorManager.clearColors(); + } + + // clean up event handlers + session.unregisterEventHandler(this); + session.close(); + CollaborationConnection conn = CollaborationConnection.getConnection(); + if (conn != null) { + conn.unregisterEventHandler(this); + } + + super.dispose(); + } + + private void disposeArrow(Image image) { + if (image != null && !image.isDisposed()) { + image.dispose(); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView#sendMessage + * () + */ + @Override + public void sendMessage() { + String message = getComposedMessage(); + if (message.length() > 0) { + try { + UserId id = CollaborationConnection.getConnection().getUser(); + appendMessage(id, System.currentTimeMillis(), message, null); + session.sendChatMessage(message); + } catch (CollaborationException e) { + // TODO Auto-generated catch block. Please revise as + // appropriate. + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * styleAndAppendText(java.lang.StringBuilder, int, java.lang.String, + * java.lang.String, java.util.List) + */ + @Override + protected void styleAndAppendText(StringBuilder sb, int offset, + String name, UserId userId, String subject, List ranges) { + RGB rgb = colorManager.getColorFromUser(userId); + if (mappedColors.get(rgb) == null) { + if (rgb == null) { + rgb = new RGB(0, 0, 0); + } + Color col = new Color(Display.getCurrent(), rgb); + mappedColors.put(rgb, col); + } + styleAndAppendText(sb, offset, name, userId, ranges, + mappedColors.get(rgb)); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * styleAndAppendText(java.lang.StringBuilder, int, java.lang.String, + * com.raytheon.uf.viz.collaboration.comm.provider.user.UserId, + * java.util.List, org.eclipse.swt.graphics.Color) + */ + @Override + protected void styleAndAppendText(StringBuilder sb, int offset, + String name, UserId userId, List ranges, Color color) { + StyleRange range = new StyleRange(messagesText.getCharCount(), offset, + color, null, SWT.NORMAL); + ranges.add(range); + if (userId != null) { + range = new StyleRange(messagesText.getCharCount() + offset, + name.length() + 1, color, null, SWT.BOLD); + } else { + range = new StyleRange(messagesText.getCharCount() + offset, + sb.length() - offset, color, null, SWT.BOLD); + } + ranges.add(range); + messagesText.append(sb.toString()); + for (StyleRange newRange : ranges) { + messagesText.setStyleRange(newRange); + } + messagesText.setTopIndex(messagesText.getLineCount() - 1); + } + + public String getRoom() { + return sessionId; + } + + @Override + protected String getSessionImageName() { + return SESSION_IMAGE_NAME; + } + + private void createArrows() { + int imgWidth = 11; + int imgHeight = 11; + + rightArrow = new Image(Display.getCurrent(), imgWidth, imgHeight); + downArrow = new Image(Display.getCurrent(), imgWidth, imgHeight); + highlightedRightArrow = new Image(Display.getCurrent(), imgWidth, + imgHeight); + highlightedDownArrow = new Image(Display.getCurrent(), imgWidth, + imgHeight); + + // the right arrow + GC gc = new GC(rightArrow); + drawArrowImage(gc, imgWidth, imgHeight, false, false); + + // the down arrow + gc = new GC(downArrow); + drawArrowImage(gc, imgWidth, imgHeight, true, false); + + // the down arrow + gc = new GC(highlightedRightArrow); + drawArrowImage(gc, imgWidth, imgHeight, false, true); + + // the down arrow + gc = new GC(highlightedDownArrow); + drawArrowImage(gc, imgWidth, imgHeight, true, true); + + gc.dispose(); + } + + private void drawArrowImage(GC gc, int imgWidth, int imgHeight, + boolean down, boolean fill) { + gc.setAntialias(SWT.ON); + // "Erase" the canvas by filling it in with a rectangle. + gc.setBackground(Display.getDefault().getSystemColor( + SWT.COLOR_WIDGET_BACKGROUND)); + gc.fillRectangle(0, 0, imgWidth, imgHeight); + gc.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK)); + int[] polyArray = null; + if (down) { + polyArray = new int[] { 2, 3, 5, 6, 8, 3 }; + } else { + polyArray = new int[] { 3, 2, 6, 5, 3, 8 }; + } + if (fill) { + gc.fillPolygon(polyArray); + } else { + gc.drawPolygon(polyArray); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * setMessageLabel(org.eclipse.swt.widgets.Label) + */ + @Override + protected void setMessageLabel(Composite comp) { + Label label = new Label(comp, SWT.WRAP); + GridData data = new GridData(SWT.FILL, SWT.NONE, true, false); + label.setLayoutData(data); + StringBuilder labelInfo = new StringBuilder(); + if (session != null) { + IVenueInfo info = session.getVenue().getInfo(); + labelInfo.append(info.getVenueSubject()); + label.setToolTipText(info.getVenueSubject()); + } + label.setText(labelInfo.toString()); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite) + */ + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + this.sessionId = site.getSecondaryId(); + this.session = (IVenueSession) CollaborationConnection.getConnection() + .getSession(this.sessionId); + initMessageArchive(); + + CollaborationConnection.getConnection().registerEventHandler(this); + + session.registerEventHandler(this); + + ((VenueSession) session).connectToRoom(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * getSessionName() + */ + @Override + protected String getSessionName() { + if (session == null) { + return sessionId; + } + return session.getVenue().getInfo().getVenueDescription(); + } + + @Subscribe + public void participantHandler(IVenueParticipantEvent event) + throws Exception { + + final ParticipantEventType type = event.getEventType(); + final IPresence presence = event.getPresence(); + final UserId participant = event.getParticipant(); + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + if (!session.isConnected() + || usersTable.getTable().isDisposed()) { + return; + } + switch (type) { + case ARRIVED: + participantArrived(participant); + break; + case DEPARTED: + participantDeparted(participant); + break; + case PRESENCE_UPDATED: + participantPresenceUpdated(participant, presence); + break; + case UPDATED: + // TODO ? + break; + default: + System.err.println("Unknown Event type"); + } + } + }); + } + + @Subscribe + public void userNicknameChanged(UserNicknameChangedEvent e) { + usersTable.refresh(); + } + + protected void participantArrived(UserId participant) { + usersTable.setInput(session.getVenue().getParticipants()); + usersTable.refresh(); + + String name = CollaborationConnection.getConnection() + .getContactsManager().getDisplayName(participant); + StringBuilder builder = new StringBuilder(name + + " has entered the room"); + sendSystemMessage(builder); + } + + protected void participantDeparted(UserId participant) { + usersTable.setInput(session.getVenue().getParticipants()); + usersTable.refresh(); + CollaborationConnection connection = CollaborationConnection + .getConnection(); + if (connection != null) { + String name = connection.getContactsManager().getDisplayName( + participant); + + StringBuilder builder = new StringBuilder(name + + " has left the room"); + sendSystemMessage(builder); + } + } + + /** + * @param participant + * @param presence + */ + protected void participantPresenceUpdated(UserId participant, + IPresence presence) { + usersTable.refresh(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.collaboration.ui.session.AbstractSessionView# + * getMessageArchive() + */ + @Override + protected SessionMsgArchive createMessageArchive() { + String sessionName = getSessionName(); + UserId me = CollaborationConnection.getConnection().getUser(); + // UserId me = session.getUserID(); + return new SessionMsgArchive(me.getHost(), me.getName(), sessionName); + } + + protected boolean isHistory(IMessage message) { + return VenueSession.SEND_HISTORY.equals(message.getStatus()); + } + + protected boolean isSelf(IMessage message, boolean isHistory) { + CollaborationConnection connection = CollaborationConnection + .getConnection(); + boolean self = message.getFrom().equals(connection.getUser()) + && !isHistory; + return self; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.IPrintableView#getStyledText + * () + */ + @Override + public StyledText getStyledText() { + return messagesText; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.collaboration.ui.session.IPrintableView#getHeaderText + * () + */ + @Override + public String getHeaderText() { + DateFormat dateFormatter = new SimpleDateFormat("dd MMM yyyy"); + return "Conversation session from room " + getSessionName() + + ", Date: " + + dateFormatter.format(msgArchive.getCreationTime()); + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SubscribeList.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SubscribeList.java new file mode 100644 index 0000000000..ff3a823f84 --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/session/SubscribeList.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.session; + +import java.util.List; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 7, 2012            mnash     Initial creation
+ * 
+ * 
+ * + * @author mnash + * @version 1.0 + */ +@DynamicSerialize +public class SubscribeList { + @DynamicSerializeElement + private List enabledSites; + + /** + * @return the enabledUsers + */ + public List getEnabledSites() { + return enabledSites; + } + + /** + * @param enabledUsers + * the enabledUsers to set + */ + public void setEnabledSites(List enabledSites) { + this.enabledSites = enabledSites; + } +} diff --git a/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/handlers/UndoRedoHandler.java b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/handlers/UndoRedoHandler.java new file mode 100644 index 0000000000..84c1efaced --- /dev/null +++ b/cave/com.raytheon.uf.viz.collaboration.ui/src/com/raytheon/uf/viz/collaboration/ui/telestrator/handlers/UndoRedoHandler.java @@ -0,0 +1,114 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.collaboration.ui.telestrator.handlers; + +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IViewReference; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.handlers.HandlerUtil; + +import com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession; +import com.raytheon.uf.viz.collaboration.display.editor.ICollaborationEditor; +import com.raytheon.uf.viz.collaboration.display.roles.dataprovider.SharedEditorsManager; +import com.raytheon.uf.viz.collaboration.display.rsc.telestrator.CollaborationDrawingResource; +import com.raytheon.uf.viz.collaboration.ui.session.CollaborationSessionView; +import com.raytheon.uf.viz.drawing.DrawingToolLayer; +import com.raytheon.viz.ui.editor.AbstractEditor; + +/** + * Action for invoking undo/redo on the CollaborationDrawingToolbar + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 24, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class UndoRedoHandler extends AbstractHandler { + + private static final String ACTION_ID = "com.raytheon.uf.viz.collaboration.tellestrator.action"; + + private static final String UNDO_ID = "UNDO"; + + private static final String REDO_ID = "REDO"; + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands. + * ExecutionEvent) + */ + @Override + public Object execute(ExecutionEvent event) throws ExecutionException { + IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindow(event); + if (window != null) { + String sessionId = null; + IEditorPart editor = HandlerUtil.getActiveEditor(event); + if (editor instanceof ICollaborationEditor) { + sessionId = ((ICollaborationEditor) editor).getSessionId(); + } else if (editor instanceof AbstractEditor) { + ISharedDisplaySession session = SharedEditorsManager + .getSharedEditorSession((AbstractEditor) editor); + if (session != null) { + sessionId = session.getSessionId(); + } + } + if (sessionId != null) { + for (IViewReference ref : window.getActivePage() + .getViewReferences()) { + if (CollaborationSessionView.ID.equals(ref.getId())) { + CollaborationSessionView view = (CollaborationSessionView) ref + .getView(false); + if (sessionId.equals(view.getSessionId())) { + CollaborationDrawingResource resource = view + .getCurrentDrawingResource(); + if (resource != null) { + DrawingToolLayer layer = resource + .getDrawingLayerFor(resource + .getMyUser()); + String action = event.getParameter(ACTION_ID); + if (UNDO_ID.equals(action)) { + layer.undo(); + } else if (REDO_ID.equals(action)) { + layer.redo(); + } + view.updateToolItems(); + break; + } + } + } + } + } + } + return null; + } +} diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DbMapResource.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DbMapResource.java index b43a7e761c..204cb8e444 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DbMapResource.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DbMapResource.java @@ -86,6 +86,7 @@ import com.vividsolutions.jts.io.WKBReader; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Feb 19, 2009 randerso Initial creation + * Sep 18, 2012 #1019 randerso improved error handling * * * @@ -526,8 +527,8 @@ public class DbMapResource extends queryJob = new MapQueryJob(); // Prepopulate fields - getLabelFields(); getGeometryType(); + getLabelFields(); getLevels(); } @@ -842,8 +843,8 @@ public class DbMapResource extends resourceData.getTable(), resourceData.getGeomField()) .getGeometryType(); } catch (Throwable e) { - statusHandler.handle(Priority.PROBLEM, - "Error querying geometry type", e); + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); } } diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DefaultDbMapQuery.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DefaultDbMapQuery.java index bc28c896df..f1f944d731 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DefaultDbMapQuery.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/DefaultDbMapQuery.java @@ -39,7 +39,8 @@ import com.vividsolutions.jts.geom.Envelope; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Dec 9, 2011 bsteffen Initial creation + * Dec 9, 2011 bsteffen Initial creation + * Sep 18, 2012 #1019 randerso cleaned up geometry type query * * * @@ -143,10 +144,16 @@ public class DefaultDbMapQuery implements DbMapQuery { query.append(schema); query.append("' AND f_table_name='"); query.append(table); - query.append("' LIMIT 1;"); + query.append("' AND f_geometry_column='"); + query.append(this.geomField); + query.append("';"); List results = DirectDbQuery.executeQuery(query.toString(), MAPS, QueryLanguage.SQL); + if (results.isEmpty()) { + throw new VizException("Maps database table \"" + table + + "\" is missing or invalid"); + } return (String) results.get(0)[0]; } diff --git a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/MapResourceGroup.java b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/MapResourceGroup.java index bb9cad5309..e7ec079da2 100644 --- a/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/MapResourceGroup.java +++ b/cave/com.raytheon.uf.viz.core.maps/src/com/raytheon/uf/viz/core/maps/rsc/MapResourceGroup.java @@ -31,10 +31,12 @@ import com.raytheon.uf.viz.core.drawables.ResourcePair; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.map.MapDescriptor; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; import com.raytheon.uf.viz.core.rsc.IResourceGroup; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.ResourceList; import com.raytheon.uf.viz.core.rsc.ResourceProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.AbstractCapability; import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability; import com.raytheon.uf.viz.core.rsc.capabilities.OutlineCapability; @@ -79,7 +81,20 @@ public class MapResourceGroup extends } }); - + this.resourceData.addChangeListener(new IResourceDataChanged() { + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.CAPABILITY + && object instanceof AbstractCapability) { + for (ResourcePair rp : resourceData.getResourceList()) { + rp.getLoadProperties() + .getCapabilities() + .addCapability( + ((AbstractCapability) object).clone()); + } + } + } + }); } protected void addListener(AbstractVizResource rsc) @@ -129,6 +144,10 @@ public class MapResourceGroup extends for (ResourcePair rp : this.resourceData.getResourceList()) { AbstractVizResource rsc = rp.getResource(); if (rsc != null) { + rsc.getCapabilities().addCapability( + getCapability(ColorableCapability.class).clone()); + rsc.getCapabilities().addCapability( + getCapability(OutlineCapability.class).clone()); rsc.init(target); } } @@ -154,13 +173,6 @@ public class MapResourceGroup extends if (properties.isDisplayable(displayWidth)) { PaintProperties newProps = new PaintProperties(paintProps); - // keep these in sync - - resource.getCapabilities().addCapability( - getCapability(ColorableCapability.class)); - resource.getCapabilities().addCapability( - getCapability(OutlineCapability.class)); - if (resource.hasCapability(ImagingCapability.class)) { paintProps.setAlpha(resource.getCapability( ImagingCapability.class).getAlpha()); diff --git a/cave/com.raytheon.uf.viz.core.rsc/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.core.rsc/META-INF/MANIFEST.MF index b2a66cdd22..8d0a8144e3 100644 --- a/cave/com.raytheon.uf.viz.core.rsc/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.core.rsc/META-INF/MANIFEST.MF @@ -14,9 +14,13 @@ Require-Bundle: org.eclipse.core.runtime, com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174", com.raytheon.uf.common.time;bundle-version="1.12.1174", org.geotools;bundle-version="2.6.4", - com.raytheon.uf.common.geospatial;bundle-version="1.12.1174" + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + com.raytheon.viz.ui.tools.map;bundle-version="1.12.1174", + com.raytheon.viz.core;bundle-version="1.12.1174" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: com.raytheon.uf.viz.core.rsc.legend, com.raytheon.uf.viz.core.rsc.sampling, - com.raytheon.uf.viz.core.rsc.sampling.actions + com.raytheon.uf.viz.core.rsc.sampling.actions, + com.raytheon.uf.viz.core.rsc.tools, + com.raytheon.uf.viz.core.rsc.tools.action diff --git a/cave/com.raytheon.uf.viz.core.rsc/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/cave/com.raytheon.uf.viz.core.rsc/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject index 12d7796884..f6781b2035 100644 --- a/cave/com.raytheon.uf.viz.core.rsc/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject +++ b/cave/com.raytheon.uf.viz.core.rsc/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -1 +1,2 @@ -com.raytheon.uf.viz.core.rsc.FirstAvailableResourceData \ No newline at end of file +com.raytheon.uf.viz.core.rsc.FirstAvailableResourceData +com.raytheon.uf.viz.core.rsc.tools.AwipsToolsResourceData \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/sampling/SamplingResource.java b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/sampling/SamplingResource.java index 35be2e99ca..c95df387f9 100644 --- a/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/sampling/SamplingResource.java +++ b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/sampling/SamplingResource.java @@ -148,8 +148,8 @@ public class SamplingResource extends protected void initInternal(IGraphicsTarget target) throws VizException { IDisplayPaneContainer container = getResourceContainer(); if (container != null) { - container - .registerMouseHandler(inputAdapter, InputPriority.RESOURCE); + container.registerMouseHandler(inputAdapter, + InputPriority.SYSTEM_RESOURCE); } hoverFont = target.initializeFont(getClass().getName()); } @@ -391,15 +391,13 @@ public class SamplingResource extends while (j < split.length) { String s = split[j]; if (s.length() + line.length() <= approxLenPerStr) { - if (!s.isEmpty()){ - if (j == split.length -1 && split[1].equalsIgnoreCase("=")) - { - line = split[split.length-1]; - } - else - { - line += " " + s; - } + if (!s.isEmpty()) { + if (j == split.length - 1 + && split[1].equalsIgnoreCase("=")) { + line = split[split.length - 1]; + } else { + line += " " + s; + } } else { line += " "; } diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/AbstractMovableToolLayer.java b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/AbstractMovableToolLayer.java similarity index 99% rename from cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/AbstractMovableToolLayer.java rename to cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/AbstractMovableToolLayer.java index 088afebb09..2e09b29783 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/layer/AbstractMovableToolLayer.java +++ b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/AbstractMovableToolLayer.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.viz.awipstools.ui.layer; +package com.raytheon.uf.viz.core.rsc.tools; import java.util.Collection; import java.util.Random; @@ -39,7 +39,6 @@ import com.raytheon.uf.viz.core.rsc.IInputHandler; import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; import com.raytheon.uf.viz.core.rsc.LoadProperties; import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; -import com.raytheon.viz.awipstools.ui.display.AwipsToolsResourceData; import com.raytheon.viz.ui.input.EditableManager; import com.vividsolutions.jts.geom.Coordinate; diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/display/AwipsToolsResourceData.java b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/AwipsToolsResourceData.java similarity index 99% rename from cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/display/AwipsToolsResourceData.java rename to cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/AwipsToolsResourceData.java index 77406b7092..a8f679e469 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/display/AwipsToolsResourceData.java +++ b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/AwipsToolsResourceData.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.viz.awipstools.ui.display; +package com.raytheon.uf.viz.core.rsc.tools; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/AbstractMapToolAction.java b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/action/AbstractMapToolAction.java similarity index 97% rename from cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/AbstractMapToolAction.java rename to cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/action/AbstractMapToolAction.java index 6144a3de3d..f3245d4372 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/AbstractMapToolAction.java +++ b/cave/com.raytheon.uf.viz.core.rsc/src/com/raytheon/uf/viz/core/rsc/tools/action/AbstractMapToolAction.java @@ -17,7 +17,7 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.viz.awipstools.ui.action; +package com.raytheon.uf.viz.core.rsc.tools.action; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; @@ -32,7 +32,7 @@ import com.raytheon.uf.viz.core.map.MapDescriptor; import com.raytheon.uf.viz.core.rsc.AbstractResourceData; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; import com.raytheon.uf.viz.core.rsc.LoadProperties; -import com.raytheon.viz.awipstools.ui.display.AwipsToolsResourceData; +import com.raytheon.uf.viz.core.rsc.tools.AwipsToolsResourceData; import com.raytheon.viz.ui.EditorUtil; import com.raytheon.viz.ui.editor.IMultiPaneEditor; import com.raytheon.viz.ui.tools.map.AbstractMapTool; diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/globals/VizGlobalsManager.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/globals/VizGlobalsManager.java index 7f1b0f1be6..9b15e56bc6 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/globals/VizGlobalsManager.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/globals/VizGlobalsManager.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; @@ -163,8 +164,12 @@ public class VizGlobalsManager { */ public void updateUI(IDisplayPaneContainer editor, IRenderableDisplay display) { - if (window.getActivePage().getActiveEditor() != editor) { - return; + if (window != null) { + // Check the active editor on the window + IWorkbenchPage page = window.getActivePage(); + if (page != null && page.getActiveEditor() != editor) { + return; + } } if (editor != null && display != null) { Map globals = display.getGlobalsMap(); diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/procedures/IAlterBundleContributor.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/procedures/IAlterBundleContributor.java index 7d65d333c1..6ec226710f 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/procedures/IAlterBundleContributor.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/procedures/IAlterBundleContributor.java @@ -30,6 +30,7 @@ import java.util.Map; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Jan 4, 2010 mschenke Initial creation + * Aug 8, 2012 875 rferrel Add separators for menu support. * * * @@ -39,6 +40,35 @@ import java.util.Map; public interface IAlterBundleContributor { + /** + * Used to separate menu from entries. This string can not be part of any + * name. An entry ending with this separator indicates a sub-menu. Entries + * not ending with the separator are menu items added to the desired menu. + * The top menu should always be created. Submenus should be create prior to + * adding entries to them. Entries should be displayed in menus in the order + * they are listed. Examples: + * + *
+     * D2D->                  -- this is a sub-menu off the top menu named: D2D
+     * Original Contributions -- A menu item placed in the main menu.
+     * D2D->Point A           -- A menu item placed in the sub menu  name: Point A
+     * ->D2D->alt->           -- A sub-menu of D2D name: alt
+     * ->D2D->alt->Alt A      -- A menu item for the above sub-menu name: Alt A
+     * 
+ */ + public final static String MENU_SEPARATOR = "->"; + + /** + * When this is the menu item's name a menu item separator entry is + * generated in the desired menu. Examples: + * + *
+     * <>            -- Place a menu item separator in the main menu.
+     * D2D-><>       -- Place a menu item separator in the D2D sub-menu
+     * 
+ */ + public final static String MI_SEPARATOR = "<>"; + /** * Get a mapping of key to alternate values for the key * diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/time/TimeMatchingJob.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/time/TimeMatchingJob.java index 82c3a7594f..fec658cd9b 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/time/TimeMatchingJob.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/time/TimeMatchingJob.java @@ -27,6 +27,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.services.IDisposable; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -57,6 +58,17 @@ public class TimeMatchingJob extends Job { private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(TimeMatchingJob.class); + static { + Activator.getDefault().registerDisposable(new IDisposable() { + @Override + public void dispose() { + shutdown(); + } + }); + } + + private static boolean running = true; + private static Map map = new ConcurrentHashMap(); private IDescriptor request; @@ -68,20 +80,35 @@ public class TimeMatchingJob extends Job { this.request = desc; } - public static synchronized void scheduleTimeMatch(IDescriptor desc) { - if (desc != null && desc.getTimeMatcher() != null) { - TimeMatchingJob job = map.get(desc); - if (job == null) { - job = new TimeMatchingJob(desc); - job.setSystem(true); - } else { - job.keepAround = true; + public static void scheduleTimeMatch(IDescriptor desc) { + synchronized (TimeMatchingJob.class) { + if (running == false) { + return; + } + if (desc != null && desc.getTimeMatcher() != null) { + TimeMatchingJob job = map.get(desc); + if (job == null) { + job = new TimeMatchingJob(desc); + job.setSystem(true); + } else { + job.keepAround = true; + } + map.put(desc, job); + job.schedule(); } - map.put(desc, job); - job.schedule(); } } + private static void shutdown() { + synchronized (TimeMatchingJob.class) { + running = false; + } + for (TimeMatchingJob job : map.values()) { + job.cancel(); + } + map.clear(); + } + /* * (non-Javadoc) * @@ -111,7 +138,6 @@ public class TimeMatchingJob extends Job { } }); } - } catch (Throwable e) { statusHandler.handle(Priority.CRITICAL, "Error redoing time matching", e); diff --git a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendClickHandler.java b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendClickHandler.java index bb89a8af89..1dfde287e0 100644 --- a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendClickHandler.java +++ b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendClickHandler.java @@ -87,7 +87,7 @@ public class D2DLegendClickHandler extends AbstractD2DLegendInputHandler { cancel = true; } // eat the movement if we initially clicked on a resource - return (mouseDownRsc != null); + return cancel; } @Override @@ -104,6 +104,7 @@ public class D2DLegendClickHandler extends AbstractD2DLegendInputHandler { // Verify we are on our own pane mouseDownRsc = resource.checkLabelSpace( display.getDescriptor(), activePane.getTarget(), x, y); + return mouseDownRsc != null; } } return false; diff --git a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendResource.java b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendResource.java index 378410ea64..993f7daa2d 100644 --- a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendResource.java +++ b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/legend/D2DLegendResource.java @@ -579,11 +579,13 @@ public class D2DLegendResource extends String name = selectedResource.getResource().getName(); if (name != null && name.isEmpty() == false) { menuManager.add(new DummyAction(name)); - TMB_ACTION.setSelectedRsc(selectedResource); - TMB_ACTION.setContainer(getResourceContainer()); - menuManager.add(TMB_ACTION); - menuManager.add(new Separator()); } + TMB_ACTION.setSelectedRsc(selectedResource); + TMB_ACTION.setContainer(getResourceContainer()); + if (TMB_ACTION.isHidden() == false) { + menuManager.add(TMB_ACTION); + } + menuManager.add(new Separator()); super.fillContextMenu(menuManager, selectedResource); } } diff --git a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/TimeMatcher.java b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/TimeMatcher.java index 59ce32760f..5835596c5c 100644 --- a/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/TimeMatcher.java +++ b/cave/com.raytheon.uf.viz.d2d.core/src/com/raytheon/uf/viz/d2d/core/time/TimeMatcher.java @@ -553,7 +553,7 @@ public class TimeMatcher { int f, f0; int p, pp, m, n, q; int best; - long dtf, dt, fd; + long dtf, dt, dtd, fd; double fo; long vf, v1, v2, vd; @@ -648,6 +648,7 @@ public class TimeMatcher { IntrinsicReturnVal rv = intrinsicPeriod(depictTimes, majorIndex, dataFcsts); dt = rv.intrinsicPeriod; + dtd = (rv.intrinsicPeriod * 3) / 2; dataFcsts = rv.haveForecasts; if (fspatial) { @@ -682,6 +683,15 @@ public class TimeMatcher { dt++; } + if (dt > dtd || frameTimes[ef].getMatchValid() - latest.getTime() > dtd) { + // The first check makes sure that dtd is always bigger than dt + // since dtd is supposed to add extra padding to the time. The + // second check makes it so that if the latest frameTime is past the + // latest depictTime by more than dtd than we ignore dtd by setting + // it to dt which makes it a no op. + dtd = dt; + } + // Try to find match for each frame. Dependent on valid times increasing // monotonically in depictTimes. for (f = f0; f <= ef; f++) { @@ -692,7 +702,17 @@ public class TimeMatcher { vf = (frameTimes)[f].getMatchValid() + deltaTime; v1 = vf - dt; // first usable valid time v2 = vf + dt; // last usable valid time - + if (!dataFcsts && !frameFcsts && vf > latest.getTime()) { + // if we are dealing with live data(without forecast times) then + // we want to allow extra time on the latest frame. For example + // LAPS data arrives hourly, and radar arrives every 6 minutes, + // in this scenario dt is around 36 minutes so 36 minutes after + // the hour when radar updates LAPS disappears. This code + // changes that so for the latest frame LAPS will be visible for + // 90 minutes which is enough time for the next LAPS frame to + // come in, this means that the latest frame always has data. + v1 = vf - dtd; + } fo = frameTimes[f].getLevelValue(); spatial = fo >= 0.0 && dspatial; best = -1; // have no best match yet diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.d2d.nsharp/META-INF/MANIFEST.MF index aa26005cd4..3b7c7b310f 100644 --- a/cave/com.raytheon.uf.viz.d2d.nsharp/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.d2d.nsharp/META-INF/MANIFEST.MF @@ -7,63 +7,25 @@ Bundle-Activator: com.raytheon.uf.viz.d2d.nsharp.Activator Bundle-Vendor: RAYTHEON Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization Require-Bundle: org.eclipse.core.runtime, - com.raytheon.uf.common.serialization;bundle-version="1.12.1174" + com.raytheon.uf.common.serialization;bundle-version="1.12.1174", + gov.noaa.nws.ncep.ui.nsharp;bundle-version="1.0.0", + org.eclipse.core.commands;bundle-version="3.6.0", + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.viz.ui;bundle-version="1.12.1174", + org.eclipse.swt;bundle-version="3.6.1", + org.eclipse.ui;bundle-version="3.6.1", + org.geotools;bundle-version="2.6.4", + gov.noaa.nws.ncep.viz.common;bundle-version="1.0.0", + gov.noaa.nws.ncep.edex.common;bundle-version="1.0.0", + com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174", + com.raytheon.uf.common.time;bundle-version="1.12.1174", + com.raytheon.uf.viz.d2d.core;bundle-version="1.12.1174", + com.raytheon.uf.common.topo;bundle-version="1.12.1174", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + com.raytheon.uf.viz.d2d.ui;bundle-version="1.12.1174", + com.raytheon.viz.core.graphing;bundle-version="1.12.1174" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy -Import-Package: com.raytheon.uf.common.dataplugin, - com.raytheon.uf.common.dataplugin.bufrua, - com.raytheon.uf.common.dataquery.requests, - com.raytheon.uf.common.dataquery.responses, - com.raytheon.uf.common.geospatial, - com.raytheon.uf.common.pointdata.spatial, - com.raytheon.uf.common.serialization.comm, - com.raytheon.uf.common.sounding, - com.raytheon.uf.common.status, - com.raytheon.uf.common.time, - com.raytheon.uf.common.topo, - com.raytheon.uf.viz.core, - com.raytheon.uf.viz.core.catalog, - com.raytheon.uf.viz.core.datastructure, - com.raytheon.uf.viz.core.drawables, - com.raytheon.uf.viz.core.exception, - com.raytheon.uf.viz.core.requests, - com.raytheon.uf.viz.core.rsc, - com.raytheon.uf.viz.core.rsc.capabilities, - com.raytheon.uf.viz.core.topo, - com.raytheon.uf.viz.d2d.core, - com.raytheon.uf.viz.d2d.core.time, - com.raytheon.viz.core.graphing, - com.raytheon.viz.ui, - com.raytheon.viz.ui.actions, - com.raytheon.viz.ui.dialogs, - com.raytheon.viz.ui.editor, - com.raytheon.viz.ui.perspectives, - com.raytheon.viz.ui.tools, - com.sun.jna.ptr, - com.vividsolutions.jts.geom, - gov.noaa.nws.ncep.edex.common.sounding, - gov.noaa.nws.ncep.ui.nsharp, - gov.noaa.nws.ncep.ui.nsharp.maprsc, - gov.noaa.nws.ncep.ui.nsharp.menu, - gov.noaa.nws.ncep.ui.nsharp.natives, - gov.noaa.nws.ncep.ui.nsharp.palette, - gov.noaa.nws.ncep.ui.nsharp.skewt, - gov.noaa.nws.ncep.ui.nsharp.skewt.bkgd, - gov.noaa.nws.ncep.ui.nsharp.skewt.rsc, - gov.noaa.nws.ncep.viz.common.soundingQuery, - gov.noaa.nws.ncep.viz.ui.display, - javax.measure.converter, - javax.measure.unit, - org.eclipse.core.commands, - org.eclipse.jface.util, - org.eclipse.swt, - org.eclipse.swt.graphics, - org.eclipse.swt.layout, - org.eclipse.swt.printing, - org.eclipse.swt.widgets, - org.eclipse.ui, - org.eclipse.ui.part, - org.geotools.coverage.grid Export-Package: com.raytheon.uf.viz.d2d.nsharp, com.raytheon.uf.viz.d2d.nsharp.display, com.raytheon.uf.viz.d2d.nsharp.rsc diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/plugin.xml b/cave/com.raytheon.uf.viz.d2d.nsharp/plugin.xml index ca965292a7..0dfa141492 100644 --- a/cave/com.raytheon.uf.viz.d2d.nsharp/plugin.xml +++ b/cave/com.raytheon.uf.viz.d2d.nsharp/plugin.xml @@ -5,7 +5,7 @@ point="com.raytheon.uf.viz.core.descriptor"> @@ -15,10 +15,10 @@ + name="NSHARP(D2D)"/> @@ -39,7 +39,7 @@ commandId="com.raytheon.viz.ui.actions.saveScreen"> - + @@ -48,10 +48,36 @@ commandId="com.raytheon.viz.ui.actions.printScreenAction"> - + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDescriptor.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDescriptor.java index 668e133302..a8ec1e5405 100644 --- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDescriptor.java +++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDescriptor.java @@ -19,111 +19,27 @@ **/ package com.raytheon.uf.viz.d2d.nsharp.display; -import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTDescriptor; -import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource; -import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource.ElementStateProperty; - -import java.util.List; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; - -import com.raytheon.uf.viz.core.datastructure.LoopProperties; -import com.raytheon.uf.viz.core.drawables.FrameCoordinator; -import com.raytheon.uf.viz.core.drawables.IDescriptor; -import com.raytheon.uf.viz.core.drawables.IFrameCoordinator; -import com.raytheon.uf.viz.d2d.core.time.D2DTimeMatcher; +import gov.noaa.nws.ncep.ui.nsharp.display.NsharpSkewTPaneDescriptor; /** - * - * A serializeable descriptor for nsharp + * This class only exists for backwards compatibility with serialized displayed, + * once all serialized procedures/bundles have been modified then this can be + * deleted. * *
- * 
+ *
  * SOFTWARE HISTORY
- * 
+ *
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Apr 12, 2011            bsteffen     Initial creation
- * 
+ * Aug 31, 2012            bsteffen     Initial creation
+ *
  * 
- * + * * @author bsteffen - * @version 1.0 + * @version 1.0 */ -@XmlAccessorType(XmlAccessType.NONE) -public class D2DNSharpDescriptor extends NsharpSkewTDescriptor { - public D2DNSharpDescriptor() { - super(); - setTimeMatcher(new D2DTimeMatcher()); - // NSharp does not handle frame changes in the descriptor so it needs a - // custom frame coordinator to handle the events using the frame - // information in the resource. - frameCoordinator = new FrameCoordinator(this) { - - @Override - public void changeFrame(LoopProperties loopProperties) { - if (loopProperties == null || !loopProperties.isLooping()) { - return; - } - NsharpSkewTResource skewRsc = getSkewtResource(); - List frames = skewRsc - .getDataTimelineList(); - if (frames == null || frames.isEmpty()) { - return; - } - // Determine wait time based off of direction - long waitTime = loopDirection > 0 ? loopProperties - .getFwdFrameTime() : loopProperties.getRevFrameTime(); - // use special wait time for first and last frame - if (frames.get(frames.size() - 1).getElementDescription() - .equals(skewRsc.getPickedStnInfoStr())) { - waitTime = loopProperties.getLastFrameDwell(); - } else if (frames.get(0).getElementDescription() - .equals(skewRsc.getPickedStnInfoStr())) { - waitTime = loopProperties.getFirstFrameDwell(); - } - // Tell the loop propertied how long to wait - loopProperties.drawAfterWait(waitTime); - - // Tell the resource to handle looping - if (loopProperties.isShouldDraw()) { - skewRsc.setLoopingDataTimeLine(loopProperties); - } - } - - @Override - public void changeFrame( - IFrameCoordinator.FrameChangeOperation operation, - IFrameCoordinator.FrameChangeMode mode) { - IDescriptor.FrameChangeOperation dop = IDescriptor.FrameChangeOperation - .valueOf(operation.name()); - IDescriptor.FrameChangeMode dmode = IDescriptor.FrameChangeMode - .valueOf(mode.name()); - D2DNSharpDescriptor.this.changeFrame(dop, dmode); - // Just hand this off to the resource. - /*switch (dmode) { - case TIME_ONLY: - getSkewtResource().setSteppingTimeLine(dop, dmode ); - break; - case SPACE_ONLY: - // noop for now - break; - case TIME_AND_SPACE: - // same as TIME_ONLY for now - getSkewtResource().setSteppingTimeLine(dop, dmode ); - break; - }*/ - } - }; - } - - @Override - public void checkDrawTime(LoopProperties loopProperties) { - // Do nothing, this is a deprecated method that should never get called - // but for some reason ncep continues writing new code that calls this - // and it continues to conflict with the frame coordinator object. - } +public class D2DNSharpDescriptor extends NsharpSkewTPaneDescriptor { } diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDisplay.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDisplay.java index 21d3d30a0f..fa32696825 100644 --- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDisplay.java +++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpDisplay.java @@ -19,36 +19,14 @@ **/ package com.raytheon.uf.viz.d2d.nsharp.display; -import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; -import gov.noaa.nws.ncep.ui.nsharp.natives.NsharpNative; -import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTDisplay; -import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource; - -import java.lang.ref.WeakReference; -import java.util.List; -import java.util.Map; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PlatformUI; - -import com.raytheon.uf.viz.core.IDisplayPane; -import com.raytheon.uf.viz.core.IGraphicsTarget; -import com.raytheon.uf.viz.core.VizConstants; -import com.raytheon.uf.viz.core.drawables.PaintProperties; -import com.raytheon.uf.viz.core.exception.VizException; -import com.raytheon.uf.viz.d2d.core.ID2DRenderableDisplay; -import com.raytheon.uf.viz.d2d.core.time.D2DTimeMatcher; -import com.raytheon.viz.ui.VizWorkbenchManager; -import com.sun.jna.ptr.FloatByReference; +import gov.noaa.nws.ncep.ui.nsharp.display.NsharpSkewTPaneDisplay; /** - * - * A Serializeable display for nsharp + * This class only exists for backwards compatibility with serialized displayed, + * once all serialized procedures/bundles have been modified then this can be + * deleted. * *
  * 
@@ -56,135 +34,14 @@ import com.sun.jna.ptr.FloatByReference;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * Apr 12, 2011            bsteffen     Initial creation
+ * Aug 31, 2012            bsteffen     Initial creation
  * 
  * 
* * @author bsteffen * @version 1.0 */ -@XmlAccessorType(XmlAccessType.NONE) @XmlRootElement -public class D2DNSharpDisplay extends NsharpSkewTDisplay implements - ID2DRenderableDisplay { - - private static WeakReference activeNativeResource; - - private double density = 1.0; - - private double magnification = 1.0; - - public D2DNSharpDisplay() { - super(); - // Super forces the Default NShaprSkewT Descriptor - setDescriptor(new D2DNSharpDescriptor()); - VizWorkbenchManager.getInstance().getCurrentWindow().getActivePage() - .addPartListener(D2DNSharpPartListener.getInstance()); - } - - @Override - public void clear(IDisplayPane parentPane) { - super.clear(parentPane); - if (getContainer() instanceof IEditorPart) { - IWorkbenchPage page = PlatformUI.getWorkbench() - .getActiveWorkbenchWindow().getActivePage(); - page.closeEditor((IEditorPart) getContainer(), false); - } - } - - @Override - public void paint(IGraphicsTarget target, PaintProperties paintProps) - throws VizException { - /** - * This whole if statement exists to manage the data stored in the - * native library, this is not a good way of handling this, it should be - * handled by a separate manager or something.T - */ - NsharpSkewTResource skewRsc = getDescriptor().getSkewtResource(); - if ((activeNativeResource == null || activeNativeResource.get() != skewRsc) - && skewRsc.getSoundingLys() != null) { - // TODO we need a better way of tracking what is in native. - List soundingLys = skewRsc.getSoundingLys(); - NsharpNative nsharpNative = skewRsc.getNsharpNative(); - - // re-populate snd data to nsharp native code lib for later - // calculating - nsharpNative.populateSndgData(soundingLys); - - if (soundingLys != null && soundingLys.size() > 0) { - // set initial hodohouseC - FloatByReference dummy1 = new FloatByReference(-999); - FloatByReference dummy2 = new FloatByReference(-999); - FloatByReference wdir = new FloatByReference(-999); - FloatByReference wspd = new FloatByReference(-999); - FloatByReference Surfpressure = new FloatByReference(-999); - nsharpNative.nsharpLib - .get_surface(Surfpressure, dummy1, dummy2); - if (nsharpNative.nsharpLib.qc(Surfpressure.getValue()) == 1) { - nsharpNative.nsharpLib.mean_wind(Surfpressure.getValue(), - nsharpNative.nsharpLib.ipres(nsharpNative.nsharpLib - .msl(6000.0F)), dummy1, dummy2, wdir, wspd); - if (nsharpNative.nsharpLib.qc(wdir.getValue()) == 1 - && nsharpNative.nsharpLib.qc(wspd.getValue()) == 1) { - // ----- Plot 30/75 Storm Motion Vector -----small light - // pink circle - float dir = (wdir.getValue() + 30.0f) % 360; - float spd = wspd.getValue() * 0.75f; - // System.out.println(spd + " "+ wspd.getValue()); - nsharpNative.nsharpLib.set_storm(spd, dir); - } - } - } - activeNativeResource = new WeakReference( - skewRsc); - } - super.paint(target, paintProps); - } - - @Override - public double getMagnification() { - return magnification; - } - - @Override - public double getDensity() { - return density; - } - - @Override - public void setMagnification(double magnification) { - this.magnification = magnification; - } - - @Override - public void setDensity(double density) { - this.density = density; - } - - @Override - public String getScale() { - return "NSharp"; - } - - @Override - public void setScale(String scale) { - if (!getScale().equals(scale)) { - throw new UnsupportedOperationException( - "NSharp display does not allow you to change scale to: " - + scale); - } - } - - @Override - public Map getGlobalsMap() { - Map globals = super.getGlobalsMap(); - globals.put(VizConstants.FRAMES_ID, new Integer(getDescriptor() - .getNumberOfFrames())); - globals.put(VizConstants.DENSITY_ID, new Double(density)); - globals.put(VizConstants.MAGNIFICATION_ID, new Double(magnification)); - globals.put(VizConstants.LOADMODE_ID, ((D2DTimeMatcher) getDescriptor() - .getTimeMatcher()).getLoadMode()); - return globals; - } +public class D2DNSharpDisplay extends NsharpSkewTPaneDisplay { } diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPaletteWindow.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPaletteWindow.java index 88fc9b593b..6227c5d3d0 100644 --- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPaletteWindow.java +++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPaletteWindow.java @@ -19,13 +19,13 @@ **/ package com.raytheon.uf.viz.d2d.nsharp.display; -import gov.noaa.nws.ncep.ui.nsharp.palette.NsharpPaletteWindow; -import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource; +import gov.noaa.nws.ncep.ui.nsharp.view.NsharpPaletteWindow; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; +import org.eclipse.ui.IViewSite; import com.raytheon.viz.ui.perspectives.AbstractVizPerspectiveManager; import com.raytheon.viz.ui.perspectives.VizPerspectiveListener; @@ -34,7 +34,9 @@ import com.raytheon.viz.ui.tools.ModalToolManager; /** * - * TODO Add Description + * Extends NsharpPaletteWindow but overide load to prevent opening ncmapeditor. + * Also disable unload since loading and unloading is being handled by time + * matched resources. * *
  * 
@@ -53,43 +55,39 @@ public class D2DNSharpPaletteWindow extends NsharpPaletteWindow {
 
     private static final String EDIT_TOOL_CATEGY = "com.raytheon.viz.ui.modalTool.nav";
 
-    private class EditTool extends AbstractModalTool {
+    private AbstractModalTool lastTool = null;
 
-        public EditTool() {
-            this.categoryId = EDIT_TOOL_CATEGY;
+    @Override
+    public void init(IViewSite site) {
+        super.init(site);
+        AbstractVizPerspectiveManager perspMgr = VizPerspectiveListener
+                .getCurrentPerspectiveManager();
+        if (perspMgr == null) {
+            return;
         }
-
-        @Override
-        protected void deactivateTool() {
-            if (!graphEditBtn.isDisposed()) {
-                editGraphOn = false;
-                graphEditBtn.setText(EDIT_GRAPH_OFF);
-                notifyRsc();
-            }
-
+        ModalToolManager mgr = perspMgr.getToolManager();
+        lastTool = mgr.getSelectedModalTool(EDIT_TOOL_CATEGY);
+        if (lastTool != null) {
+            mgr.deselectModalTool(lastTool);
         }
-
-        @Override
-        protected void activateTool() {
-            editGraphOn = true;
-            graphEditBtn.setText(EDIT_GRAPH_ON);
-            notifyRsc();
-        }
-
-        private void notifyRsc() {
-            NsharpSkewTResource rsc = getSkewTRsc();
-            if (rsc == null)
-                return;
-
-            rsc.setEditGraphOn(editGraphOn);
-            rsc.issueRefresh();
-        }
-
     }
 
-    private AbstractModalTool editTool = new EditTool();
-
-    private AbstractModalTool lastTool = null;
+    @Override
+    public void dispose() {
+        super.dispose();
+        AbstractVizPerspectiveManager perspMgr = VizPerspectiveListener
+                .getCurrentPerspectiveManager();
+        if (perspMgr == null) {
+            return;
+        }
+        ModalToolManager mgr = perspMgr.getToolManager();
+        if (lastTool != null
+                && mgr.getSelectedModalTool(EDIT_TOOL_CATEGY) == null) {
+            mgr.selectModalTool(lastTool);
+            lastTool.activate();
+            lastTool = null;
+        }
+    }
 
     @Override
     public void createDataControlGp(Composite parent) {
@@ -108,71 +106,6 @@ public class D2DNSharpPaletteWindow extends NsharpPaletteWindow {
             }
         });
 
-        for (Listener listener : graphEditBtn.getListeners(SWT.MouseUp)) {
-            graphEditBtn.removeListener(SWT.MouseUp, listener);
-        }
-        graphEditBtn.addListener(SWT.MouseUp, new Listener() {
-
-            @Override
-            public void handleEvent(Event event) {
-                if (editGraphOn) {
-                    disableEdit();
-                } else {
-                    enableEdit();
-                }
-            }
-        });
-        NsharpSkewTResource rsc = getSkewTRsc();
-        if (rsc != null && rsc.isEditGraphOn()) {
-            enableEdit();
-        } else {
-            disableEdit();
-        }
-
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see gov.noaa.nws.ncep.ui.nsharp.palette.NsharpPaletteWindow#dispose()
-     */
-    @Override
-    public void dispose() {
-        disableEdit();
-        getSite().getPage().removePartListener(this);
-    }
-
-    private void enableEdit() {
-        AbstractVizPerspectiveManager perspMgr = VizPerspectiveListener
-                .getCurrentPerspectiveManager();
-        if (perspMgr == null) {
-            return;
-        }
-        ModalToolManager mgr = perspMgr.getToolManager();
-        lastTool = mgr.getSelectedModalTool(EDIT_TOOL_CATEGY);
-        if (lastTool != editTool) {
-            mgr.selectModalTool(editTool);
-            editTool.activate();
-        } else {
-            lastTool = null;
-        }
-    }
-
-    private void disableEdit() {
-        AbstractVizPerspectiveManager perspMgr = VizPerspectiveListener
-                .getCurrentPerspectiveManager();
-        if (perspMgr == null) {
-            return;
-        }
-        ModalToolManager mgr = perspMgr.getToolManager();
-        if (mgr.getSelectedModalTool(EDIT_TOOL_CATEGY) == editTool) {
-            mgr.deselectModalTool(editTool);
-            if (lastTool != null) {
-                mgr.selectModalTool(lastTool);
-                lastTool.activate();
-                lastTool = null;
-            }
-        }
     }
 
 }
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPartListener.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPartListener.java
index cc82d702a2..0f89458b53 100644
--- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPartListener.java
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNSharpPartListener.java
@@ -19,20 +19,26 @@
  **/
 package com.raytheon.uf.viz.d2d.nsharp.display;
 
-import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTEditor;
+import gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor;
 
+import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IEditorReference;
 import org.eclipse.ui.IPartListener2;
 import org.eclipse.ui.IViewPart;
 import org.eclipse.ui.IViewReference;
 import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
 import org.eclipse.ui.IWorkbenchPartReference;
+import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.PartInitException;
 
 import com.raytheon.uf.common.status.IUFStatusHandler;
 import com.raytheon.uf.common.status.UFStatus;
 import com.raytheon.uf.common.status.UFStatus.Priority;
-import com.raytheon.uf.viz.core.drawables.IRenderableDisplay;
+import com.raytheon.uf.viz.core.IDisplayPane;
+import com.raytheon.uf.viz.core.VizApp;
+import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
+import com.raytheon.viz.ui.VizWorkbenchManager;
 
 /**
  * 
@@ -58,30 +64,55 @@ public class D2DNSharpPartListener implements IPartListener2 {
     private static final String VIEW_ID = D2DNSharpPaletteWindow.class
             .getCanonicalName();
 
-    private static D2DNSharpPartListener instance;
+    private final AbstractVizResource resource;
 
-    private D2DNSharpPartListener() {
+    public D2DNSharpPartListener(AbstractVizResource resource) {
+        this.resource = resource;
     }
 
-    public static D2DNSharpPartListener getInstance() {
-        if (instance != null) {
-            return instance;
-        }
-        synchronized (D2DNSharpPartListener.class) {
-            if (instance == null) {
-                instance = new D2DNSharpPartListener();
+    public void enable() {
+        VizApp.runAsync(new Runnable() {
+
+            @Override
+            public void run() {
+                IWorkbenchPage page = VizWorkbenchManager.getInstance()
+                        .getCurrentWindow().getActivePage();
+                page.addPartListener(D2DNSharpPartListener.this);
+                for (IEditorReference editor : page.getEditorReferences()) {
+                    if (page.isPartVisible(editor.getEditor(false))) {
+                        partVisible(editor);
+                    }
+                }
             }
-            return instance;
-        }
+        });
+    }
+
+    public void disable() {
+        VizApp.runAsync(new Runnable() {
+            @Override
+            public void run() {
+                IWorkbenchWindow window = VizWorkbenchManager.getInstance()
+                        .getCurrentWindow();
+                if (window == null) {
+                    // window will be null when CAVE is shutting down
+                    return;
+                }
+                IWorkbenchPage page = window.getActivePage();
+                page.removePartListener(D2DNSharpPartListener.this);
+            }
+        });
     }
 
     private boolean isD2DNSharpPart(IWorkbenchPartReference partRef) {
-        if (partRef.getPart(false) instanceof NsharpSkewTEditor) {
-            NsharpSkewTEditor editor = (NsharpSkewTEditor) partRef
-                    .getPart(false);
-            IRenderableDisplay display = editor.getActiveDisplayPane()
-                    .getRenderableDisplay();
-            return display instanceof D2DNSharpDisplay;
+        IWorkbenchPart part = partRef.getPart(false);
+        if (part instanceof NsharpEditor) {
+            NsharpEditor editor = (NsharpEditor) part;
+            for (IDisplayPane pane : editor.getDisplayPanes()) {
+                if (pane.getRenderableDisplay().getDescriptor() == resource
+                        .getDescriptor()) {
+                    return true;
+                }
+            }
         }
         return false;
     }
@@ -117,26 +148,33 @@ public class D2DNSharpPartListener implements IPartListener2 {
             IWorkbenchPage page = partRef.getPage();
             IViewPart view = page.findView(VIEW_ID);
             if (view != null) {
-                if (page.getActivePart() == view) {
-                    // TODO find a better solution to this problem.
-                    // It seems like when switching perspectives with the view
-                    // we want to hide active hideView causes an exception.
-                    // Making another view active fixes this.
-                    for (IViewReference viewRef : page.getViewReferences()) {
-                        if (viewRef.getView(false) != view) {
-                            page.activate(viewRef.getView(false));
-                            break;
-                        }
+                boolean hide = true;
+                // set visible for any other visible editors, for when there are
+                // two nsharp editors visible and one goes invisible.
+                for (IEditorReference editorRef : page.getEditorReferences()) {
+                    IEditorPart editor = editorRef.getEditor(false);
+                    if (page.isPartVisible(editor)
+                            && editor instanceof NsharpEditor) {
+                        hide = false;
                     }
                 }
-                page.hideView(view);
-            }
-            // set visible for any other visible editors, for when there are two
-            // nsharp editors visible and one goes invisible.
-            for (IEditorReference editor : page.getEditorReferences()) {
-                if (page.isPartVisible(editor.getEditor(false))) {
-                    partVisible(editor);
+                if (hide) {
+                    if (page.getActivePart() == view) {
+                        // TODO find a better solution to this problem.
+                        // It seems like when switching perspectives with the
+                        // view we want to hide active hideView causes an
+                        // exception.
+                        // Making another view active fixes this.
+                        for (IViewReference viewRef : page.getViewReferences()) {
+                            if (viewRef.getView(false) != view) {
+                                page.activate(viewRef.getView(false));
+                                break;
+                            }
+                        }
+                    }
+                    page.hideView(view);
                 }
+
             }
         }
 
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNsharpHandleArchiveFile.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNsharpHandleArchiveFile.java
index 8f6b58bf34..c1b6928e59 100644
--- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNsharpHandleArchiveFile.java
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/display/D2DNsharpHandleArchiveFile.java
@@ -21,9 +21,9 @@ package com.raytheon.uf.viz.d2d.nsharp.display;
 
 import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer;
 import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo;
+import gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor;
+import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpResourceHandler;
 import gov.noaa.nws.ncep.ui.nsharp.natives.NsharpDataHandling;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTEditor;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -305,10 +305,9 @@ public class D2DNsharpHandleArchiveFile {
             throw new VizException("No valid sounding layers found in data");
         }
 
-        NsharpSkewTEditor skewtEdt = NsharpSkewTEditor
-                .createOrOpenSkewTEditor();
-        NsharpSkewTResource skewRsc = skewtEdt.getNsharpSkewTDescriptor()
-                .getSkewtResource();
+        NsharpEditor skewtEdt = NsharpEditor
+                .createOrOpenEditor();
+        NsharpResourceHandler skewRsc = skewtEdt.getRscHandler();
         Map> soundingLysLstMap = new HashMap>();
         soundingLysLstMap.put(stninfo.getStnDisplayInfo(), layers);
         skewRsc.addRsc(soundingLysLstMap, stninfo);
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResource.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResource.java
index b6ac9b30c4..b6330b7810 100644
--- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResource.java
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResource.java
@@ -21,8 +21,8 @@ package com.raytheon.uf.viz.d2d.nsharp.rsc;
 
 import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer;
 import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTDescriptor;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource;
+import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpAbstractPaneResource;
+import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpResourceHandler;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -40,13 +40,15 @@ import org.eclipse.core.runtime.jobs.Job;
 
 import com.raytheon.uf.common.time.DataTime;
 import com.raytheon.uf.viz.core.IGraphicsTarget;
-import com.raytheon.uf.viz.core.drawables.IDescriptor.FrameChangeMode;
-import com.raytheon.uf.viz.core.drawables.IDescriptor.FrameChangeOperation;
+import com.raytheon.uf.viz.core.drawables.AbstractDescriptor;
 import com.raytheon.uf.viz.core.drawables.PaintProperties;
 import com.raytheon.uf.viz.core.exception.VizException;
 import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
 import com.raytheon.uf.viz.core.rsc.IResourceDataChanged;
 import com.raytheon.uf.viz.core.rsc.LoadProperties;
+import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder;
+import com.raytheon.uf.viz.core.rsc.ResourceProperties;
+import com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpPartListener;
 
 /**
  * 
@@ -67,7 +69,7 @@ import com.raytheon.uf.viz.core.rsc.LoadProperties;
  * @version 1.0
  */
 public class D2DNSharpResource extends
-        AbstractVizResource {
+        AbstractVizResource {
 
     // A map of all the plugin data objects for times we have data.
     private Map pdos = new HashMap();
@@ -98,6 +100,8 @@ public class D2DNSharpResource extends
 
     };
 
+    private D2DNSharpPartListener partListener;
+
     public D2DNSharpResource(D2DNSharpResourceData resourceData,
             LoadProperties loadProperties) {
         super(resourceData, loadProperties);
@@ -117,16 +121,14 @@ public class D2DNSharpResource extends
     @Override
     protected void paintInternal(IGraphicsTarget target,
             PaintProperties paintProps) throws VizException {
-        NsharpSkewTResource skewRsc = descriptor.getSkewtResource();
-        if (skewRsc == null) {
-            return;
-        }
+        NsharpResourceHandler handler = getHandler();
+        // Last time I checked if you try to add or remove data from nsharp on
+        // non-UI threads it can cause major sync issues so all changes to
+        // nsharp are done in the paint loop.
         if (!soundingsToRemove.isEmpty()) {
-            // If this happens on the wrong thread than NsharpSkewTResource
-            // blows up on threading problems.
             List soundingsToRemove = this.soundingsToRemove;
             this.soundingsToRemove = new ArrayList();
-            skewRsc.deleteRsc(soundingsToRemove);
+            handler.deleteRsc(soundingsToRemove);
             issueRefresh();
         }
         if (!dataResponseQueue.isEmpty()) {
@@ -146,32 +148,7 @@ public class D2DNSharpResource extends
             if (stnInfo == null) {
                 return;
             }
-            String picked = skewRsc.getPickedStnInfoStr();
-            // For some reason this has to happen on the UI thread, so do it in
-            // paint.
-            skewRsc.addRsc(myDataMap, stnInfo);
-            // Adding to nsharp changes the frame but in D2D we like to keep the
-            // current frame.
-            backToPicked : while (picked != null
-                    && !skewRsc.getPickedStnInfoStr().equals(picked)) {
-                String initStn = skewRsc.getPickedStnInfoStr().substring(0, 4);
-                do { // for each station...
-                    String initTimePickedStnInfoStr = skewRsc.getPickedStnInfoStr();
-                    do { // ...for each time
-                        skewRsc.setSteppingTimeLine(FrameChangeOperation.NEXT, FrameChangeMode.TIME_ONLY);
-                        // see if we're back home; if so, success
-                        if (skewRsc.getPickedStnInfoStr().equals(picked)) {
-                            break backToPicked;
-                        }
-                        // if we've cycled through all times for this station...
-                    } while (!skewRsc.getPickedStnInfoStr().equals(initTimePickedStnInfoStr));
-                    // ...then go to the next station
-                    skewRsc.setSteppingStnIdList(FrameChangeOperation.NEXT);
-                    // if we've cycled through all stations without a station/time match...
-                } while (!skewRsc.getPickedStnInfoStr().substring(0, 4).equals(initStn));
-                // ...then something is wrong
-                //TODO:  consider logging internal error here? -- original "picked" station/time not found
-            }
+            handler.addRsc(myDataMap, stnInfo, false);
             issueRefresh();
         }
     }
@@ -201,10 +178,22 @@ public class D2DNSharpResource extends
         return false;
     }
 
+    private NsharpResourceHandler getHandler() throws VizException {
+        List paneRscs = descriptor
+                .getResourceList().getResourcesByTypeAsType(
+                        NsharpAbstractPaneResource.class);
+        for (NsharpAbstractPaneResource paneRsc : paneRscs) {
+            NsharpResourceHandler handler = paneRsc.getRscHandler();
+            if (handler != null) {
+                return handler;
+            }
+        }
+        throw new VizException("Unable to find a NsharpResourceHandler.");
+    }
+
     @Override
     protected void initInternal(IGraphicsTarget target) throws VizException {
-        descriptor.getSkewtResource().setSoundingType(
-                resourceData.getSoundingType());
+        getHandler().setSoundingType(resourceData.getSoundingType());
         // listen for updates
         resourceData.addChangeListener(new IResourceDataChanged() {
 
@@ -221,6 +210,8 @@ public class D2DNSharpResource extends
             }
 
         });
+        partListener = new D2DNSharpPartListener(this);
+        partListener.enable();
     }
 
     @Override
@@ -243,6 +234,9 @@ public class D2DNSharpResource extends
             this.remove(time);
         }
         dataRequestJob.cancel();
+        if (partListener != null) {
+            partListener.disable();
+        }
     }
 
     public Collection getTimeLineElements() {
@@ -255,8 +249,24 @@ public class D2DNSharpResource extends
 
     @Override
     public String getName() {
-        return "D2D " + resourceData.getSoundingType() + " "
+        return "D2D NSharp " + resourceData.getSoundingType() + " "
                 + resourceData.getPointName();
     }
 
+    @Override
+    public ResourceOrder getResourceOrder() {
+        // Have to be highest resource since the builtin nsharp resources are
+        // unknown and they have to be at index 0 on the list or nsharp code
+        // breaks.
+        return ResourceOrder.HIGHEST;
+    }
+
+    @Override
+    protected void setProperties(ResourceProperties properties) {
+        // Have to be highest resource since the builtin nsharp resources are
+        // unknown and they have to be at index 0 on the list or nsharp code
+        // breaks.
+        properties.setRenderingOrder(ResourceOrder.HIGHEST);
+    }
+
 }
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResourceData.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResourceData.java
index e629f4381f..e754ae596c 100644
--- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResourceData.java
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/D2DNSharpResourceData.java
@@ -25,9 +25,6 @@ import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile;
 import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo;
 import gov.noaa.nws.ncep.ui.nsharp.natives.NsharpDataHandling;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -41,8 +38,6 @@ import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 
-import org.eclipse.core.runtime.Platform;
-
 import com.raytheon.uf.common.dataplugin.PluginDataObject;
 import com.raytheon.uf.common.time.DataTime;
 import com.raytheon.uf.common.time.DataTime.FLAG;
@@ -162,8 +157,6 @@ public abstract class D2DNSharpResourceData extends
         List layers = profileList.getSoundingLyLst();
         layers = NsharpDataHandling.organizeSoundingDataForShow(layers,
                 profileList.getStationElevation());
-        // TODO remove this, as it only exists to help resolve crashes.
-        logSoundingFiles(dataObject.getStationInfo(), layers);
         dataObject.setLayers(layers);
     }
 
@@ -261,87 +254,4 @@ public abstract class D2DNSharpResourceData extends
         return true;
     }
 
-    // TODO this purges debugging files, it can be removed when debugging is
-    // removed
-    private static long nextPurgeTime = 0;
-
-    /**
-     * 
-     * This function exists only to help identify data that can crash nsharp, it
-     * can be removed once nsharp is considered more stable.
-     * 
-     * @param info
-     * @param layers
-     */
-    private static void logSoundingFiles(NsharpStationInfo info,
-            List layers) {
-        if (layers.isEmpty()) {
-            return;
-        }
-        try {
-            File caveData = new File(Platform.getUserLocation().getURL()
-                    .getPath());
-            File logs = new File(caveData, "logs");
-            if (!logs.exists()) {
-                logs.mkdir();
-            }
-            File nsharpFiles = new File(logs, "nsharpFiles");
-            if (!nsharpFiles.exists()) {
-                nsharpFiles.mkdir();
-            }
-            if (nextPurgeTime < System.currentTimeMillis()) {
-                // delete anything more than 3 hours old.
-                long lastValidTime = System.currentTimeMillis() - 3 * 60 * 60
-                        * 1000l;
-                for (File file : nsharpFiles.listFiles()) {
-                    if (file.lastModified() < lastValidTime) {
-                        file.delete();
-                    }
-                }
-                // run again in an hour.
-                nextPurgeTime = System.currentTimeMillis() + 60 * 60 * 1000l;
-            }
-
-            // EGM: Win32 can't have ':' in filenames
-            String logFilename = info.getStnDisplayInfo() + ".nsp";
-            logFilename = logFilename.replace(":", "_");
-            File nspFile = new File(nsharpFiles, logFilename);
-
-            FileWriter fstream = new FileWriter(nspFile);
-            BufferedWriter out = new BufferedWriter(fstream);
-            String textToSave = new String("");
-
-            List soundLyList = layers;
-            String latlonstr;
-            latlonstr = "  LAT=" + info.getLatitude() + " LON="
-                    + info.getLongitude();
-            textToSave = info.getSndType()
-                    + " "
-                    + info.getSndType()
-                    + "  "
-                    + info.getStnDisplayInfo()
-                    + latlonstr
-                    + "\n"
-                    + "PRESSURE  HGHT\t   TEMP\t  DWPT    WDIR     WSPD    OMEG\n";
-
-            String tempText = "";
-            for (NcSoundingLayer layer : soundLyList) {
-                tempText = String.format("%f  %f  %f  %f  %f  %f  %f\n",
-                        layer.getPressure(), layer.getGeoHeight(),
-                        layer.getTemperature(), layer.getDewpoint(),
-                        layer.getWindDirection(), layer.getWindSpeed(),
-                        layer.getOmega());
-                textToSave = textToSave + tempText;
-            }
-            out.write(textToSave);
-            // Close the output stream
-            out.close();
-            nspFile.deleteOnExit();
-        } catch (Throwable e) {
-            // Ignore all errors, this operation does not need to complete
-            // normally if something goes wrong
-            e.printStackTrace();
-        }
-    }
-
 }
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpPrintScreenAction.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpPrintScreenAction.java
index 84d04a9990..897061d61f 100644
--- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpPrintScreenAction.java
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpPrintScreenAction.java
@@ -20,29 +20,25 @@
 
 package com.raytheon.uf.viz.d2d.nsharp.rsc.action;
 
-import gov.noaa.nws.ncep.ui.nsharp.palette.NsharpPrintHandle;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTDescriptor;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTEditor;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource;
-import gov.noaa.nws.ncep.ui.nsharp.skewt.rsc.NsharpSkewTResource.ElementStateProperty;
+
+import gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor;
+import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpResourceHandler;
+import gov.noaa.nws.ncep.ui.nsharp.view.NsharpPrintHandle;
 
 import org.eclipse.core.commands.ExecutionEvent;
 import org.eclipse.core.commands.ExecutionException;
 import org.eclipse.swt.printing.PrintDialog;
-import org.eclipse.swt.printing.Printer;
 import org.eclipse.swt.printing.PrinterData;
-import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.PlatformUI;
 
 import com.raytheon.uf.viz.core.IDisplayPane;
-import com.raytheon.uf.viz.core.drawables.IDescriptor;
-import com.raytheon.uf.viz.core.drawables.IFrameCoordinator.FrameChangeMode;
-import com.raytheon.uf.viz.core.drawables.IFrameCoordinator.FrameChangeOperation;
+import com.raytheon.uf.viz.core.datastructure.LoopProperties;
 import com.raytheon.uf.viz.core.exception.VizException;
 import com.raytheon.viz.ui.EditorUtil;
 import com.raytheon.viz.ui.actions.PrintScreenAction;
+import com.raytheon.viz.ui.editor.AbstractEditor;
 
 /**
  * Print the current map
@@ -71,18 +67,16 @@ public class NSharpPrintScreenAction extends PrintScreenAction {
      */
     @Override
     public Object execute(ExecutionEvent event) throws ExecutionException {
-        NsharpSkewTEditor editor = null;
+        NsharpEditor editor = null;
         IEditorPart part = EditorUtil.getActiveEditor();
-        if (part instanceof NsharpSkewTEditor) {
-            editor = (NsharpSkewTEditor) part;
+        if (part instanceof NsharpEditor) {
+            editor = (NsharpEditor) part;
         }
         if (editor == null) {
             return super.execute(event);
         }
-        IDisplayPane pane = editor.getActiveDisplayPane();
-        IDescriptor desc = pane.getDescriptor();
 
-        NsharpSkewTDescriptor ndesc = editor.getNsharpSkewTDescriptor();
+        NsharpResourceHandler handler = ((NsharpEditor) editor).getRscHandler();
 
         Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                 .getShell();
@@ -93,8 +87,8 @@ public class NSharpPrintScreenAction extends PrintScreenAction {
         if (frameMode == null || frameMode.equalsIgnoreCase("current")) {
             // selection doesn't seem to work.
             pd.setScope(PrinterData.PAGE_RANGE);
-            pd.setStartPage(getCurrentIndex(ndesc.getSkewtResource()) + 1);
-            pd.setEndPage(getCurrentIndex(ndesc.getSkewtResource()) + 1);
+            pd.setStartPage(NsharpFrameIndexUtil.getCurrentIndex(handler) + 1);
+            pd.setEndPage(NsharpFrameIndexUtil.getCurrentIndex(handler) + 1);
         } else if (frameMode.equalsIgnoreCase("all")) {
             pd.setScope(PrinterData.ALL_PAGES);
         } else {
@@ -129,7 +123,7 @@ public class NSharpPrintScreenAction extends PrintScreenAction {
                 break;
             }
             case PrinterData.SELECTION: {
-                printImage(handle, editor);
+                printImage(handle);
                 break;
             }
             }
@@ -140,60 +134,34 @@ public class NSharpPrintScreenAction extends PrintScreenAction {
         return null;
     }
 
-    private int getCurrentIndex(NsharpSkewTResource rsc) {
-        int index = rsc.getDataTimelineList().size();
-        for (ElementStateProperty element : rsc.getDataTimelineList()) {
-            index -= 1;
-            if (element.getElementDescription().equals(
-                    rsc.getPickedStnInfoStr())) {
-                return index;
-            }
-        }
-        return 0;
-    }
 
-    private void printAllFrames(NsharpPrintHandle printer,
-            NsharpSkewTEditor editor) throws VizException {
-        printFrames(printer, editor, 0, editor.getNsharpSkewTDescriptor()
-                .getSkewtResource().getDataTimelineList().size());
-    }
 
-    private void printFrames(NsharpPrintHandle printer,
-            NsharpSkewTEditor editor, int startIndex, int endIndex)
+    private void printAllFrames(NsharpPrintHandle printer, NsharpEditor editor)
             throws VizException {
-        NsharpSkewTDescriptor ndesc = editor.getNsharpSkewTDescriptor();
-        IDisplayPane pane = editor.getActiveDisplayPane();
-        String picked = ndesc.getSkewtResource().getPickedStnInfoStr();
-        if (getCurrentIndex(ndesc.getSkewtResource()) > startIndex) {
-            ndesc.getFrameCoordinator().changeFrame(FrameChangeOperation.FIRST,
-                    FrameChangeMode.TIME_AND_SPACE);
-            editor.getActiveDisplayPane().refresh();
-        }
-        renderPane(pane, editor.getLoopProperties());
-        boolean first = true;
-        for (int i = getCurrentIndex(ndesc.getSkewtResource()); i < endIndex; i++) {
-            if (!first) {
-                ndesc.getFrameCoordinator().changeFrame(
-                        FrameChangeOperation.NEXT,
-                        FrameChangeMode.TIME_AND_SPACE);
-                pane.refresh();
-                renderPane(pane, editor.getLoopProperties());
-            }
-            if (i >= startIndex) {
-                printImage(printer, editor);
-            }
-            first = false;
-        }
-        while (!ndesc.getSkewtResource().getPickedStnInfoStr().equals(picked)) {
-            ndesc.getFrameCoordinator().changeFrame(FrameChangeOperation.NEXT,
-                    FrameChangeMode.TIME_AND_SPACE);
-            pane.refresh();
-            renderPane(pane, editor.getLoopProperties());
-        }
+        printFrames(printer, editor, 0, NsharpFrameIndexUtil.getFrameCount(editor.getRscHandler()));
     }
 
-    private void printImage(NsharpPrintHandle printer, NsharpSkewTEditor editor) {
-        printer.printPage(editor.getNsharpSkewTDescriptor());
+    private void printFrames(NsharpPrintHandle printer, NsharpEditor editor,
+            int startIndex, int endIndex) throws VizException {
+        NsharpResourceHandler handler = ((NsharpEditor) editor).getRscHandler();
+        IDisplayPane pane = editor.getActiveDisplayPane();
+        int startingIndex = NsharpFrameIndexUtil.getCurrentIndex(handler);
+        LoopProperties loopProperties = ((AbstractEditor) editor)
+                .getLoopProperties();
+        renderPane(pane, loopProperties);
+        for (int i = startIndex; i < endIndex; i++) {
+            NsharpFrameIndexUtil.setCurrentIndex(handler, i);
+            pane.refresh();
+            renderPane(pane, loopProperties);
+            printImage(printer);
+        }
+        NsharpFrameIndexUtil.setCurrentIndex(handler, startingIndex);
+        pane.refresh();
+        renderPane(pane, loopProperties);
+    }
+
+    private void printImage(NsharpPrintHandle printer) {
+        printer.printPage();
     }
 
 }
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpSaveScreenAction.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpSaveScreenAction.java
index 29d395c758..1a8d15ee50 100644
--- a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpSaveScreenAction.java
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NSharpSaveScreenAction.java
@@ -20,16 +20,15 @@
 
 package com.raytheon.uf.viz.d2d.nsharp.rsc.action;
 
-import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTDescriptor;
+import gov.noaa.nws.ncep.ui.nsharp.display.NsharpEditor;
+import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpResourceHandler;
 
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.List;
 
 import com.raytheon.uf.viz.core.IDisplayPane;
-import com.raytheon.uf.viz.core.drawables.IDescriptor;
-import com.raytheon.uf.viz.core.drawables.IFrameCoordinator.FrameChangeMode;
-import com.raytheon.uf.viz.core.drawables.IFrameCoordinator.FrameChangeOperation;
+import com.raytheon.uf.viz.core.datastructure.LoopProperties;
 import com.raytheon.uf.viz.core.exception.VizException;
 import com.raytheon.viz.ui.actions.SaveScreenAction;
 import com.raytheon.viz.ui.editor.AbstractEditor;
@@ -58,51 +57,38 @@ public class NSharpSaveScreenAction extends SaveScreenAction {
     @Override
     protected List captureAllFrames(AbstractEditor editor)
             throws VizException {
-        IDescriptor desc = editor.getActiveDisplayPane().getDescriptor();
-        if (!(desc instanceof NsharpSkewTDescriptor)) {
+        if(!(editor instanceof NsharpEditor)){
             return super.captureAllFrames(editor);
         }
-        NsharpSkewTDescriptor ndesc = (NsharpSkewTDescriptor) desc;
+        NsharpResourceHandler handler = ((NsharpEditor) editor).getRscHandler();
         int startIndex = 0;
-        int endIndex = ndesc.getSkewtResource().getDataTimelineList().size();
+        int endIndex = NsharpFrameIndexUtil.getFrameCount(handler);
         return captureFrames(editor, startIndex, endIndex);
     }
 
     @Override
     protected List captureFrames(AbstractEditor editor,
             int startIndex, int endIndex) throws VizException {
-        IDisplayPane pane = editor.getActiveDisplayPane();
-        IDescriptor desc = pane.getDescriptor();
-        if (!(desc instanceof NsharpSkewTDescriptor)) {
+        if(!(editor instanceof NsharpEditor)){
             return super.captureFrames(editor, startIndex, endIndex);
         }
-        NsharpSkewTDescriptor ndesc = (NsharpSkewTDescriptor) desc;
+        IDisplayPane pane = editor.getActiveDisplayPane();
+        NsharpResourceHandler handler = ((NsharpEditor) editor).getRscHandler();
         // save the frame we are on;
-        String picked = ndesc.getSkewtResource().getPickedStnInfoStr();
+        int startingIndex = NsharpFrameIndexUtil.getCurrentIndex(handler);
         List images = new ArrayList();
-
-        desc.getFrameCoordinator().changeFrame(FrameChangeOperation.FIRST,
-                FrameChangeMode.TIME_AND_SPACE);
-        pane.refresh();
-        renderPane(pane, editor.getLoopProperties());
-        for (int i = 0; i < endIndex; i++) {
-            if (i >= startIndex) {
-                images.add(captureCurrentFrames(editor));
-            }
-            if (i < endIndex - 1) {
-                desc.getFrameCoordinator().changeFrame(
-                        FrameChangeOperation.NEXT,
-                        FrameChangeMode.TIME_AND_SPACE);
-                pane.refresh();
-                renderPane(pane, editor.getLoopProperties());
-            }
-        }
-        while (!ndesc.getSkewtResource().getPickedStnInfoStr().equals(picked)) {
-            desc.getFrameCoordinator().changeFrame(FrameChangeOperation.NEXT,
-                    FrameChangeMode.TIME_AND_SPACE);
+        LoopProperties loopProperties = ((AbstractEditor) editor)
+                .getLoopProperties();
+        renderPane(pane, loopProperties);
+        for (int i = startIndex; i < endIndex; i++) {
+            NsharpFrameIndexUtil.setCurrentIndex(handler, i);
             pane.refresh();
-            renderPane(pane, editor.getLoopProperties());
+            renderPane(pane, loopProperties);
+            images.add(captureCurrentFrames(editor));
         }
+        NsharpFrameIndexUtil.setCurrentIndex(handler, startingIndex);
+        pane.refresh();
+        renderPane(pane, loopProperties);
         return images;
     }
 
diff --git a/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NsharpFrameIndexUtil.java b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NsharpFrameIndexUtil.java
new file mode 100644
index 0000000000..d1143a6e20
--- /dev/null
+++ b/cave/com.raytheon.uf.viz.d2d.nsharp/src/com/raytheon/uf/viz/d2d/nsharp/rsc/action/NsharpFrameIndexUtil.java
@@ -0,0 +1,108 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ * 
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ * 
+ * Contractor Name:        Raytheon Company
+ * Contractor Address:     6825 Pine Street, Suite 340
+ *                         Mail Stop B8
+ *                         Omaha, NE 68106
+ *                         402.291.0100
+ * 
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.viz.d2d.nsharp.rsc.action;
+
+import gov.noaa.nws.ncep.ui.nsharp.NsharpSoundingElementStateProperty;
+import gov.noaa.nws.ncep.ui.nsharp.display.rsc.NsharpResourceHandler;
+
+import java.util.List;
+
+import com.raytheon.uf.viz.core.drawables.IFrameCoordinator.FrameChangeMode;
+import com.raytheon.uf.viz.core.drawables.IFrameCoordinator.FrameChangeOperation;
+
+/**
+ * Provide convenience methods for treating nsharp frames as an indexable
+ * one-dimensional list.
+ * 
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 4, 2012            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class NsharpFrameIndexUtil { + + public static int getFrameCount(NsharpResourceHandler handler){ + int count = 0; + for (List list : handler.getStnTimeTable()) { + count += list.size(); + } + return count; + } + + public static int getCurrentIndex(NsharpResourceHandler handler) { + int index = 0; + + for (List list : handler + .getStnTimeTable()) { + for (NsharpSoundingElementStateProperty element : list) { + if (element.getElementDescription().equals( + handler.getCurSndProfileProp().getElementDescription())) { + return index; + } + index += 1; + } + } + return 0; + } + + public static void setCurrentIndex(NsharpResourceHandler handler, int index) { + NsharpSoundingElementStateProperty selected = null; + int i = 0; + for (List list : handler + .getStnTimeTable()) { + for (NsharpSoundingElementStateProperty element : list) { + if (i == index) { + selected = element; + break; + } + i += 1; + } + if (selected != null) { + break; + } + } + if (selected == null) { + return; + } + NsharpSoundingElementStateProperty current = handler + .getCurSndProfileProp(); + while (!current.getStnDescription() + .equals(selected.getStnDescription())) { + handler.setSteppingStnIdList(FrameChangeOperation.NEXT); + current = handler.getCurSndProfileProp(); + } + while (!current.getElementDescription().equals( + selected.getElementDescription())) { + handler.setSteppingTimeLine(FrameChangeOperation.NEXT, + FrameChangeMode.TIME_ONLY); + current = handler.getCurSndProfileProp(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.d2d.ui/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.d2d.ui/META-INF/MANIFEST.MF index f3904a18bc..a95b61cc8c 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.d2d.ui/META-INF/MANIFEST.MF @@ -19,7 +19,9 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.core.expressions, com.raytheon.uf.viz.core.maps;bundle-version="1.0.0", com.raytheon.viz.core;bundle-version="1.12.1130", - com.raytheon.uf.viz.core.rsc;bundle-version="1.0.0" + com.raytheon.uf.viz.core.rsc;bundle-version="1.0.0", + com.raytheon.viz.ui;bundle-version="1.12.1174", + com.raytheon.uf.viz.points;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Import-Package: com.raytheon.uf.common.colormap, diff --git a/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml b/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml index f535f25036..d407ceff4a 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml +++ b/cave/com.raytheon.uf.viz.d2d.ui/plugin.xml @@ -1895,12 +1895,6 @@ contextId="com.raytheon.uf.viz.d2d.ui" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="NUMPAD_DECIMAL"/> - - - diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DensityHandler.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DensityHandler.java index 8ab9ca185e..1e5ce692d1 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DensityHandler.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/DensityHandler.java @@ -81,7 +81,7 @@ public class DensityHandler extends AbstractHandler implements IElementUpdater { IDisplayPane[] panes = container.getDisplayPanes(); for (IDisplayPane pane : panes) { IRenderableDisplay disp = pane.getRenderableDisplay(); - if (disp != null) { + if (disp != null && disp instanceof ID2DRenderableDisplay) { ((ID2DRenderableDisplay) disp).setDensity(density); } } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/MagHandler.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/MagHandler.java index 4e613951fd..59e5f06137 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/MagHandler.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/MagHandler.java @@ -73,11 +73,12 @@ public class MagHandler extends AbstractHandler implements IElementUpdater { double magnification = Double.parseDouble((arg0 .getParameter("magnification"))); if (editor != null) { - if (magnification == 0.0f) magnification=0.1; + if (magnification == 0.0f) + magnification = 0.1; IDisplayPane[] panes = editor.getDisplayPanes(); for (IDisplayPane pane : panes) { IRenderableDisplay disp = pane.getRenderableDisplay(); - if (disp != null) { + if (disp != null && disp instanceof ID2DRenderableDisplay) { ((ID2DRenderableDisplay) disp) .setMagnification(magnification); } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/AlterBundleDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/AlterBundleDlg.java index 5a4a0e0798..58b2b64582 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/AlterBundleDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/AlterBundleDlg.java @@ -20,6 +20,7 @@ package com.raytheon.uf.viz.d2d.ui.dialogs.procedures; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -27,22 +28,28 @@ import java.util.Map.Entry; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; 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.Label; import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.procedures.AlterBundleFactory; import com.raytheon.uf.viz.core.procedures.Bundle; import com.raytheon.uf.viz.core.procedures.IAlterBundleContributor; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; +import com.raytheon.viz.ui.widgets.MenuButton; /** - * TODO Add Description + * Dialog for selecting an alternate bundle. * *
  * 
@@ -54,6 +61,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
  *                                      to bundle on Load. Prevents
  *                                      the window's 'x' close from
  *                                      trying to perform a load.
+ * Jul 31, 2012 #875       rferrel     Use MenuButton to organize entries
+ *                                      in  menus.
  * 
  * 
* @@ -61,6 +70,16 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * @version 1.0 */ public class AlterBundleDlg extends CaveSWTDialog { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(AlterBundleDlg.class); + + private static final String Top_MENU_KEY = ""; + + private static final String MENU_SEP = IAlterBundleContributor.MENU_SEPARATOR; + + private static final String MI_SEP = IAlterBundleContributor.MI_SEPARATOR; + + private static final int MENU_SEP_LEN = MENU_SEP.length(); private static class AlterBundleEntry { @@ -101,14 +120,17 @@ public class AlterBundleDlg extends CaveSWTDialog { @Override protected void initializeComponents(Shell shell) { Composite mainComposite = new Composite(shell, SWT.NONE); - GridLayout mainLayout = new GridLayout(3, false); + GridLayout mainLayout = new GridLayout(1, true); mainComposite.setLayout(mainLayout); initializeCombos(mainComposite); initializeBottomButtons(mainComposite); } - private void initializeCombos(Composite comp) { + private void initializeCombos(Composite parent) { + Composite comp = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(3, false); + comp.setLayout(layout); for (IAlterBundleContributor contrib : AlterBundleFactory .getContributors()) { Map alterables = contrib.getAlterables(); @@ -143,27 +165,13 @@ public class AlterBundleDlg extends CaveSWTDialog { Label label = new Label(comp, SWT.CENTER); label.setText(entry.getKey() + " = "); - final Combo valueCbo = new Combo(comp, SWT.DROP_DOWN); - gd = new GridData(SWT.CENTER, SWT.CENTER, false, true); - valueCbo.setLayoutData(gd); - - String[] values = entry.getValue(); - valueCbo.setItems(values); - if (values.length > 0) { - valueCbo.select(0); - } - final AlterBundleEntry abe = new AlterBundleEntry(); abe.contributor = contrib; abe.alterKey = entry.getKey(); - if (values.length > 0) { - abe.alterValue = valueCbo.getItem(valueCbo - .getSelectionIndex()); - } entries.add(abe); contribEntries.add(abe); - valueCbo.addSelectionListener(new SelectionAdapter() { + SelectionListener listener = new SelectionAdapter() { /* * (non-Javadoc) * @@ -173,10 +181,19 @@ public class AlterBundleDlg extends CaveSWTDialog { */ @Override public void widgetSelected(SelectionEvent e) { - abe.alterValue = valueCbo.getItem(valueCbo - .getSelectionIndex()); + MenuButton menuButton = (MenuButton) e.getSource(); + String value = menuButton.getSelectedItem().getText(); + abe.alterValue = value; } - }); + }; + MenuButton menuButton = new MenuButton(comp); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + menuButton.setLayoutData(gd); + menuButton.addSelectionListener(listener); + Menu menu = new Menu(menuButton); + MenuItem topMi = createMenu(menu, entry); + menuButton.setMenu(menu); + menuButton.setSelectedItem(topMi); ++i; } @@ -184,14 +201,95 @@ public class AlterBundleDlg extends CaveSWTDialog { } } - private void initializeBottomButtons(Composite comp) { - Composite buttonComp = new Composite(comp, SWT.NONE); - GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, true); - gd.horizontalSpan = 3; - buttonComp.setLayoutData(gd); + private MenuItem createMenu(Menu topMenu, Entry entry) { + Map menuMap = new HashMap(); + menuMap.put(Top_MENU_KEY, topMenu); + + Menu menu = null; + MenuItem mi = null; + MenuItem topMi = null; + + for (String value : entry.getValue()) { + if (value.startsWith(MENU_SEP)) { + value = value.substring(MENU_SEP_LEN); + } + + if (!value.contains(MENU_SEP)) { + menu = menuMap.get(Top_MENU_KEY); + if (value.equals(MI_SEP)) { + new MenuItem(menu, SWT.SEPARATOR); + } else { + mi = new MenuItem(menu, SWT.PUSH); + mi.setText(value); + if (topMi == null) { + topMi = mi; + } + } + } else if (value.endsWith(MENU_SEP)) { + // create new sub menu here. + menu = menuMap.get(value); + if (menu == null) { + String[] vals = parseNameParentKey(value); + String name = vals[0]; + String parentKey = vals[1]; + Menu parentMenu = menuMap.get(parentKey); + if (parentMenu != null) { + menu = new Menu(parentMenu); + mi = new MenuItem(parentMenu, SWT.CASCADE); + mi.setMenu(menu); + mi.setText(name); + menuMap.put(value, menu); + } else { + statusHandler.handle(Priority.DEBUG, + "Attempting to recreate a menu: " + value); + } + } + } else { + // Add item to the desired menu + String[] vals = parseNameParentKey(value); + String name = vals[0]; + String parentKey = vals[1]; + menu = menuMap.get(parentKey); + if (menu != null) { + if (name.equals(MI_SEP)) { + mi = new MenuItem(menu, SWT.SEPARATOR); + } else { + mi = new MenuItem(menu, SWT.NONE); + mi.setText(name); + } + } else { + statusHandler.handle(Priority.DEBUG, + "Attempting to add an item to non-existent menu: " + + value); + } + } + } + return topMi; + } + + private String[] parseNameParentKey(String value) { + String[] vals = value.split(MENU_SEP); + String name = vals[vals.length - 1]; + String parentKey = null; + if (vals.length == 1) { + parentKey = Top_MENU_KEY; + } else { + StringBuilder sb = new StringBuilder(); + for (int j = 0; j < vals.length - 1; ++j) { + sb.append(vals[j]).append(MENU_SEP); + } + parentKey = sb.toString(); + } + return new String[] { name, parentKey }; + } + + private void initializeBottomButtons(Composite parent) { + Composite buttonComp = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, true); buttonComp.setLayout(layout); + GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, true); + buttonComp.setLayoutData(gd); loadBtn = new Button(buttonComp, SWT.PUSH); loadBtn.setText("Load"); diff --git a/cave/com.raytheon.uf.viz.d2d.xy.adapters/src/com/raytheon/uf/viz/d2d/xy/adapters/crosssection/GridCSAdapter.java b/cave/com.raytheon.uf.viz.d2d.xy.adapters/src/com/raytheon/uf/viz/d2d/xy/adapters/crosssection/GridCSAdapter.java index 80a03fac39..04b8d14118 100644 --- a/cave/com.raytheon.uf.viz.d2d.xy.adapters/src/com/raytheon/uf/viz/d2d/xy/adapters/crosssection/GridCSAdapter.java +++ b/cave/com.raytheon.uf.viz.d2d.xy.adapters/src/com/raytheon/uf/viz/d2d/xy/adapters/crosssection/GridCSAdapter.java @@ -71,6 +71,8 @@ import com.vividsolutions.jts.geom.Coordinate; * Feb 04, 2011 7953 bkowal Fill values will now be placed * in the data array for anything * below 300MB for RUC80. + * Oct 2, 2012 DR 15259 M.Porricelli Allow plotting when 3 levels + * available (DGEX) * *
* @@ -147,7 +149,7 @@ public class GridCSAdapter extends AbstractCrossSectionAdapter { } } - if (xMap.size() < 4) { + if (xMap.size() < 3) { return null; } @@ -161,7 +163,7 @@ public class GridCSAdapter extends AbstractCrossSectionAdapter { xMap.keySet().retainAll(yMap.keySet()); yMap.keySet().retainAll(xMap.keySet()); - if (xMap.size() < 4) { + if (xMap.size() < 3) { return null; } diff --git a/cave/com.raytheon.uf.viz.derivparam.python/localization/derivedParameters/functions/Cape.py b/cave/com.raytheon.uf.viz.derivparam.python/localization/derivedParameters/functions/Cape.py index 360cd01367..cc3c7bc057 100644 --- a/cave/com.raytheon.uf.viz.derivparam.python/localization/derivedParameters/functions/Cape.py +++ b/cave/com.raytheon.uf.viz.derivparam.python/localization/derivedParameters/functions/Cape.py @@ -122,6 +122,13 @@ def capeFunc(usetv, p_dat, tve_dat, p0, th0, sh0, ptop = None): p0 = np.copy(p0) th0 = np.copy(th0) sh0 = np.copy(sh0) + + p_dat[np.isnan(p_dat)] = 1e37 + tve_dat[np.isnan(tve_dat)] = 1e37 + p0[np.isnan(p0)] = 1e37 + th0[np.isnan(th0)] = 1e37 + sh0[np.isnan(sh0)] = 1e37 + p_dat.resize((nz, nx * ny,)) tve_dat.resize((nz, nx * ny,)) p0.resize((p0.size,)) diff --git a/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/DerivParamLocalizationAdapter.java b/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/DerivParamLocalizationAdapter.java index 3eaaacb64b..70417e4476 100644 --- a/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/DerivParamLocalizationAdapter.java +++ b/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/DerivParamLocalizationAdapter.java @@ -51,8 +51,8 @@ public class DerivParamLocalizationAdapter extends // TODO: Think of other right click actions that might be desirable if (selectedData.length == 1 && selectedData[0].getClass() == FileTreeEntryData.class) { - menuMgr.add(new NewDerivedParameterAction()); - return true; + IMenuManager newMenu = menuMgr.findMenuUsingPath(NEW_ID); + newMenu.add(new NewDerivedParameterAction()); } return false; } diff --git a/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/actions/NewDerivedParameterAction.java b/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/actions/NewDerivedParameterAction.java index f6ae73ce67..ccaf452309 100644 --- a/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/actions/NewDerivedParameterAction.java +++ b/cave/com.raytheon.uf.viz.derivparam.ui/src/com/raytheon/uf/viz/derivparam/ui/actions/NewDerivedParameterAction.java @@ -49,7 +49,7 @@ public class NewDerivedParameterAction extends Action { * */ public NewDerivedParameterAction() { - super("New..."); + super("Derived Parameter..."); } @Override diff --git a/cave/com.raytheon.uf.viz.drawing/.classpath b/cave/com.raytheon.uf.viz.drawing/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.drawing/.project b/cave/com.raytheon.uf.viz.drawing/.project new file mode 100644 index 0000000000..53c7e67a4a --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.drawing + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.drawing/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.drawing/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..0f72a13b05 --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Mar 26 17:37:45 CDT 2012 +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/cave/com.raytheon.uf.viz.drawing/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.drawing/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..06b6faf4ff --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/META-INF/MANIFEST.MF @@ -0,0 +1,21 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Drawing +Bundle-SymbolicName: com.raytheon.uf.viz.drawing;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.drawing.Activator +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Bundle-Vendor: RAYTHEON +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.viz.core.rsc;bundle-version="1.0.0", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + com.raytheon.viz.ui;bundle-version="1.12.1174", + org.geotools, + com.raytheon.viz.core;bundle-version="1.12.1174" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Import-Package: com.raytheon.uf.common.time, + com.vividsolutions.jts.geom +Export-Package: com.raytheon.uf.viz.drawing diff --git a/cave/com.raytheon.uf.viz.drawing/build.properties b/cave/com.raytheon.uf.viz.drawing/build.properties new file mode 100644 index 0000000000..79785acaee --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + icons/,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.drawing/icons/draw.gif b/cave/com.raytheon.uf.viz.drawing/icons/draw.gif new file mode 100644 index 0000000000..0bfecd50ee Binary files /dev/null and b/cave/com.raytheon.uf.viz.drawing/icons/draw.gif differ diff --git a/cave/com.raytheon.uf.viz.drawing/icons/eraser.png b/cave/com.raytheon.uf.viz.drawing/icons/eraser.png new file mode 100644 index 0000000000..bc6a3fa43a Binary files /dev/null and b/cave/com.raytheon.uf.viz.drawing/icons/eraser.png differ diff --git a/cave/com.raytheon.uf.viz.drawing/icons/eraser_box.gif b/cave/com.raytheon.uf.viz.drawing/icons/eraser_box.gif new file mode 100644 index 0000000000..48b0dcccc9 Binary files /dev/null and b/cave/com.raytheon.uf.viz.drawing/icons/eraser_box.gif differ diff --git a/cave/com.raytheon.uf.viz.drawing/icons/redo.gif b/cave/com.raytheon.uf.viz.drawing/icons/redo.gif new file mode 100644 index 0000000000..c84e5b1d84 Binary files /dev/null and b/cave/com.raytheon.uf.viz.drawing/icons/redo.gif differ diff --git a/cave/com.raytheon.uf.viz.drawing/icons/remove.gif b/cave/com.raytheon.uf.viz.drawing/icons/remove.gif new file mode 100644 index 0000000000..b6922ac11c Binary files /dev/null and b/cave/com.raytheon.uf.viz.drawing/icons/remove.gif differ diff --git a/cave/com.raytheon.uf.viz.drawing/icons/undo.gif b/cave/com.raytheon.uf.viz.drawing/icons/undo.gif new file mode 100644 index 0000000000..eae118ad16 Binary files /dev/null and b/cave/com.raytheon.uf.viz.drawing/icons/undo.gif differ diff --git a/cave/com.raytheon.uf.viz.drawing/plugin.xml b/cave/com.raytheon.uf.viz.drawing/plugin.xml new file mode 100644 index 0000000000..5eb191a1bb --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/plugin.xml @@ -0,0 +1,23 @@ + + + + + diff --git a/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/Activator.java b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/Activator.java new file mode 100644 index 0000000000..688297645f --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/Activator.java @@ -0,0 +1,50 @@ +package com.raytheon.uf.viz.drawing; + +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.raytheon.uf.viz.drawing"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * 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; + } + +} diff --git a/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/DrawingToolLayer.java b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/DrawingToolLayer.java new file mode 100644 index 0000000000..09fee0c7e3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/DrawingToolLayer.java @@ -0,0 +1,721 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.drawing; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.geotools.coverage.grid.GeneralGridGeometry; +import org.geotools.geometry.jts.JTS; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.datum.PixelInCell; +import org.opengis.referencing.operation.MathTransform; +import org.opengis.referencing.operation.TransformException; + +import com.raytheon.uf.common.geospatial.TransformFactory; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.core.drawables.IRenderable; +import com.raytheon.uf.viz.core.drawables.IWireframeShape; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.TopologyException; + +/** + * Drawing layer that can draw lines and handle undo/redo/clear/erase + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 23, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DrawingToolLayer implements IRenderable { + + public static enum DrawMode { + NONE, DRAW, ERASE; + } + + public static class StackFrame { + /** The collection of geometries displayed at a given frame */ + public Collection geometries; + + public StackFrame(Collection geometries) { + this.geometries = geometries; + } + } + + /** The factory used for geometry construction */ + private static final GeometryFactory factory = new GeometryFactory(); + + /** + * Stack for undo operations. Currently size is unlimited, may want to limit + * to specific size at some point + */ + protected Stack undoStack; + + /** Stack for redo operations */ + protected Stack redoStack; + + /** Wireframe shape for display of currentData frame */ + private IWireframeShape wireframeShape; + + /** Currently displayed frame */ + protected StackFrame currentData; + + /** Color of the data */ + private RGB color = new RGB(155, 155, 155); + + /** Line width of the data */ + private int lineWidth = 2; + + /** Eraser width to use when erasing */ + private int eraserWidth = 4; + + /** Line style of the data drawn */ + private LineStyle lineStyle = LineStyle.DEFAULT; + + /** + * Draw mode of the data (NONE,DRAW,ERASE). Used when + * {@link #addCoordinate(Coordinate)} is called + */ + private DrawMode drawMode = DrawMode.NONE; + + /** + * The line currently being drawn through {@link #addCoordinate(Coordinate)} + * calls before {@link #doneDrawing()} is called + */ + private Geometry currentDrawingLine; + + /** + * The line currently being drawn through {@link #addCoordinate(Coordinate)} + * calls before {@link #doneErasing()} is called + */ + private Geometry currentErasingLine; + + /** + * The collection of geometries the {@link #currentErasingLine} is operating + * on + */ + private Collection currentErasingGeometries; + + /** + * Flag that erasing is finished and a new stack frame should be created + * next time {@link #processErase(IExtent, Rectangle)} is called + */ + private boolean addErasingEventToStack = false; + + /** The {@link GeneralGridGeometry} we are drawing to */ + private GeneralGridGeometry targetGeometry; + + /** + * Cached "world" to grid {@link MathTransform} ({@link StackFrame} + * geometries are stored in grid space) + */ + private MathTransform worldToGrid; + + /** + * Construct a DrawingToolLayer that will draw to the + * {@link GeneralGridGeometry} passed in + * + * @param targetGeometry + */ + public DrawingToolLayer(GeneralGridGeometry targetGeometry) { + setTargetGeometry(targetGeometry); + undoStack = new Stack(); + redoStack = new Stack(); + currentData = new StackFrame(new ArrayList(0)); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.drawables.IRenderable#paint(com.raytheon.uf. + * viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + public void paint(IGraphicsTarget target, PaintProperties paintProps) + throws VizException { + synchronized (currentData) { + // Process erase coordinates before drawing data for current frame + processErase(paintProps.getView().getExtent(), + paintProps.getCanvasBounds()); + + if (wireframeShape == null) { + Collection geoms = currentErasingGeometries != null ? currentErasingGeometries + : currentData.geometries; + if (geoms != null && geoms.size() > 0) { + // No wireframe shape and we have data, create for drawing + wireframeShape = target.createWireframeShape(false, + targetGeometry); + int totalPoints = 0; + for (Geometry geom : geoms) { + totalPoints += geom.getNumPoints(); + } + wireframeShape.allocate(totalPoints * 3 * 8); + for (Geometry geom : geoms) { + handle(wireframeShape, geom); + } + wireframeShape.compile(); + } + } + if (wireframeShape != null) { + // We have data to draw, draw it + target.drawWireframeShape(wireframeShape, color, lineWidth, + lineStyle); + } + + // Render any line currently being drawn through addCoordinate(...) + if (currentDrawingLine != null + && currentDrawingLine.getNumPoints() > 1) { + IWireframeShape tmpShape = target.createWireframeShape(true, + targetGeometry); + tmpShape.allocate(currentDrawingLine.getNumPoints() * 3 * 8); + handle(tmpShape, currentDrawingLine); + target.drawWireframeShape(tmpShape, color, lineWidth, lineStyle); + tmpShape.dispose(); + } + } + } + + /** + * Processes the erase line currently constructed from + * {@link #addCoordinate(Coordinate)} while in "ERASE" {@link DrawMode} + * + * @param extent + * @param canvasSize + */ + public void processErase(IExtent extent, Rectangle canvasSize) { + synchronized (currentData) { + if (currentErasingLine != null + && currentErasingLine.getNumPoints() > 0) { + if (currentErasingGeometries == null) { + currentErasingGeometries = new ArrayList( + currentData.geometries); + } + + // Calculate world grid to canvas grid ratio + double ratio = extent.getWidth() / canvasSize.width; + // Get the size to buffer the eraser line for differencing + double bufferSize = (ratio * eraserWidth) / 2; + + // Flatten all eraser line geometries into a single list + List eraserLines = new ArrayList( + currentErasingLine.getNumGeometries()); + flattenGeometry(currentErasingLine, eraserLines); + + boolean change = false; + List newGeoms = new ArrayList( + currentErasingGeometries.size()); + + // For each eraser line, run against currentData + for (Geometry eraserLine : eraserLines) { + eraserLine = eraserLine.buffer(bufferSize); + newGeoms = new ArrayList( + currentErasingGeometries.size()); + for (Geometry geom : currentErasingGeometries) { + if (geom.intersects(eraserLine)) { + // Eraser line intersects, create difference + Geometry diff = geom.difference(eraserLine); + // Mark change flag + change = true; + if (diff instanceof GeometryCollection == false) { + // To avoid self intersecting lines, this + // will split the difference geometry + Coordinate[] coords = diff.getCoordinates(); + diff = diff.union(factory + .createPoint(coords[0])); + } + // Add diff to newGeoms + flattenGeometry(diff, newGeoms); + } else { + // Add old geometry, no changes + newGeoms.add(geom); + } + } + // These are the new "currentGeoms" for the next eraser line + currentErasingGeometries = newGeoms; + } + + if (change && wireframeShape != null) { + // In else if since addCurrentDataToStack will destroy + // wireframeShape for us + wireframeShape.dispose(); + wireframeShape = null; + } + currentErasingLine = null; + } + + if (addErasingEventToStack) { + // If data changed and we should add a new frame, do it + addErasingEventToStack = false; + if (currentErasingGeometries != null) { + addCurrentDataToStack(undoStack); + redoStack.clear(); + currentData.geometries = currentErasingGeometries; + currentErasingGeometries = null; + } + } + } + } + + /** + * Recursively adds LineString objects in the geom to wireframeShape + * + * @param wireframeShape + * @param geom + */ + private void handle(IWireframeShape wireframeShape, Geometry geom) { + if (geom instanceof GeometryCollection) { + for (int n = 0; n < geom.getNumGeometries(); ++n) { + handle(wireframeShape, geom.getGeometryN(n)); + } + } else if (geom instanceof LineString) { + Coordinate[] coords = geom.getCoordinates(); + double[][] points = new double[coords.length][]; + for (int i = 0; i < coords.length; ++i) { + points[i] = new double[] { coords[i].x, coords[i].y, + coords[i].z }; + } + wireframeShape.addLineSegment(points); + } + } + + /** + * Disposes the data in the layer + */ + public void dispose() { + synchronized (currentData) { + if (wireframeShape != null) { + wireframeShape.dispose(); + } + currentData.geometries.clear(); + currentDrawingLine = null; + undoStack.clear(); + redoStack.clear(); + } + } + + /** + * Adds a coordinate to the layer, coordinate is processed based on + * {@link #drawMode}. Coordinate should be in {@link #targetGeometry} + * "world" spacing + * + * @param coord + */ + public void addCoordinate(Coordinate coord) { + synchronized (currentData) { + // Convert coord to targetGeometry grid space + double[] point = new double[] { coord.x, coord.y, coord.z }; + if (worldToGrid != null) { + double[] out = new double[point.length]; + try { + worldToGrid.transform(point, 0, out, 0, 1); + point = out; + } catch (TransformException e) { + UFStatus.getHandler().handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + Coordinate newCoord = new Coordinate(point[0], point[1], point[2]); + Geometry toAddto = null; + if (drawMode == DrawMode.DRAW) { + if (currentDrawingLine == null) { + currentDrawingLine = factory.createPoint(newCoord); + } else { + toAddto = currentDrawingLine; + } + } else if (drawMode == DrawMode.ERASE) { + if (currentErasingLine == null) { + currentErasingLine = factory.createPoint(newCoord); + } else { + toAddto = currentErasingLine; + } + } + if (toAddto != null) { + // This will flatten the new line into a geometry collection so + // it is not self intersecting and errors will not occur + int numGeoms = toAddto.getNumGeometries(); + // The last geometry in the collection is the one to append the + // coordinate to + Geometry last = toAddto.getGeometryN(numGeoms - 1); + Coordinate[] coords = last.getCoordinates(); + Coordinate[] newCoords = Arrays.copyOf(coords, + coords.length + 1); + newCoords[newCoords.length - 1] = newCoord; + Geometry newGeom = null; + try { + // Create new LineString with newCoords + newGeom = factory.createLineString(newCoords).union( + factory.createPoint(coords[0])); + } catch (TopologyException e) { + // Can't keep adding to this line, create new one from last + // coordinate and newGeom will be collection with both + newGeom = factory.createGeometryCollection(new Geometry[] { + last, + factory.createLineString(new Coordinate[] { + coords[coords.length - 1], newCoord }) }); + } + + List newGeoms = new ArrayList(numGeoms); + for (int n = 0; n < numGeoms - 1; ++n) { + // Don't grab the last one (newGeoms - 1) since it will be + // included in newGeom + newGeoms.add(toAddto.getGeometryN(n)); + } + if (newGeoms.size() > 0) { + // geoms still in toAddto, flatten our newGeom object into + // newGeoms list and create collection + flattenGeometry(newGeom, newGeoms); + newGeom = factory.createGeometryCollection(newGeoms + .toArray(new Geometry[newGeoms.size()])); + } + + // Set newGeom to proper line + if (toAddto == currentDrawingLine) { + currentDrawingLine = newGeom; + } else { + currentErasingLine = newGeom; + } + } + } + } + + /** + * Should be called when no more coordinates will be added to + * {@link #addCoordinate(Coordinate)} and the line should be processed as + * is. A new stack frame will be created with the new line in it + */ + public void doneDrawing() { + synchronized (currentData) { + if (currentDrawingLine != null + && currentDrawingLine.getNumPoints() > 1) { + // Have data to process + try { + addCurrentDataToStack(undoStack); + List newGeometries = new ArrayList( + currentData.geometries); + flattenGeometry(currentDrawingLine, newGeometries); + currentData.geometries = newGeometries; + redoStack.clear(); + } catch (Exception e) { + UFStatus.getHandler().handle(Priority.PROBLEM, + "Could not add line, bad geometry", e); + } + } + currentDrawingLine = null; + } + } + + /** + * Recursively adds all non GeometryCollection geometries to geoms + * + * @param geom + * @param geoms + */ + public void flattenGeometry(Geometry geom, List geoms) { + if (geom instanceof GeometryCollection) { + for (int n = 0; n < geom.getNumGeometries(); ++n) { + flattenGeometry(geom.getGeometryN(n), geoms); + } + } else { + geoms.add(geom); + } + } + + /** + * Should be called when no more coordinates will be added to + * {@link #addCoordinate(Coordinate)} and the line should be processed as + * is. A new stack frame will be created with the new line in it + */ + public void doneErasing() { + synchronized (currentData) { + addErasingEventToStack = true; + } + } + + /** + * Returns true if an undo operation is capable of being processed + * + * @return + */ + public boolean canUndo() { + return undoStack.size() > 0; + } + + /** + * Returns true if a redo operation is capable of being processed + * + * @return + */ + public boolean canRedo() { + return redoStack.size() > 0; + } + + /** + * Returns true if a clear operation is capable of being processed + * + * @return + */ + public boolean canClear() { + return currentData.geometries.size() > 0 || redoStack.size() > 0; + } + + /** + * Undo the last drawing action + */ + public void undo() { + pushPop(undoStack, redoStack); + } + + /** + * Redo the last undone drawing action + */ + public void redo() { + pushPop(redoStack, undoStack); + } + + /** + * Clears the current display, a new stack frame is created. This operation + * is "undoable" by calling {@link #undo()} + */ + public void clear() { + synchronized (currentData) { + if (currentData.geometries.size() > 0) { + addCurrentDataToStack(undoStack); + currentData.geometries.clear(); + } + redoStack.clear(); + } + } + + /** + * Pushes currentData on pushStack and pops next frame from popStack and + * puts in currentData + * + * @param user + * @param popFrom + * @param pushTo + */ + private void pushPop(Stack popFrom, Stack pushTo) { + synchronized (currentData) { + if (popFrom.size() > 0) { + // There is something to undo, add current data to redoStack + addCurrentDataToStack(pushTo); + StackFrame prevFrame = popFrom.pop(); + currentData.geometries = new ArrayList( + prevFrame.geometries); + } + } + } + + /** + * Method to add the current data for the user to the user's stack. This + * method is not thread safe and needs to be wrapped in a synchronize block + * on currentData. Returns the current data for the user which will no + * longer be in currentData + * + * @param user + * @return + */ + private void addCurrentDataToStack(Stack stack) { + StackFrame oldData = new StackFrame(new ArrayList( + currentData.geometries)); + stack.push(oldData); + if (wireframeShape != null) { + wireframeShape.dispose(); + wireframeShape = null; + } + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /** + * @param lineWidth + * the lineWidth to set + */ + public void setLineWidth(int lineWidth) { + this.lineWidth = lineWidth; + } + + /** + * @param lineStyle + * the lineStyle to set + */ + public void setLineStyle(LineStyle lineStyle) { + this.lineStyle = lineStyle; + } + + /** + * @param eraserWidth + * the eraserWidth to set + */ + public void setEraserWidth(int eraserWidth) { + this.eraserWidth = eraserWidth; + } + + /** + * @return the drawMode + */ + public DrawMode getDrawMode() { + return drawMode; + } + + /** + * @param drawMode + * the drawMode to set + */ + public void setDrawMode(DrawMode drawMode) { + if (this.drawMode != drawMode) { + this.drawMode = drawMode; + currentDrawingLine = null; + } + } + + private void setTargetGeometry(GeneralGridGeometry targetGeometry) { + try { + this.targetGeometry = targetGeometry; + this.worldToGrid = TransformFactory.worldToGrid(targetGeometry, + PixelInCell.CELL_CENTER); + } catch (FactoryException e) { + UFStatus.getHandler().handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + + /** + * Reprojects the layer data for the new targetGeometry + * + * @param targetGeometry + */ + public void reproject(GeneralGridGeometry targetGeometry) { + synchronized (currentData) { + try { + MathTransform oldGridToNewGrid = TransformFactory + .gridCellToGridCell(this.targetGeometry, + PixelInCell.CELL_CENTER, targetGeometry, + PixelInCell.CELL_CENTER); + if (oldGridToNewGrid != null) { + Map projectionMap = new HashMap(); + for (StackFrame sf : undoStack) { + sf.geometries = reprojectCollection(sf.geometries, + projectionMap, oldGridToNewGrid); + } + for (StackFrame sf : redoStack) { + sf.geometries = reprojectCollection(sf.geometries, + projectionMap, oldGridToNewGrid); + } + currentData.geometries = reprojectCollection( + currentData.geometries, projectionMap, + oldGridToNewGrid); + currentDrawingLine = JTS.transform(currentDrawingLine, + oldGridToNewGrid); + } + } catch (Exception e) { + UFStatus.getHandler().handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + setTargetGeometry(targetGeometry); + if (wireframeShape != null) { + wireframeShape.dispose(); + wireframeShape = null; + } + } + } + + private Collection reprojectCollection( + Collection geometries, Map cache, + MathTransform transform) { + List newGeoms = new ArrayList(geometries.size()); + for (Geometry geom : geometries) { + Geometry projected = cache.get(geom); + if (projected == null) { + try { + projected = JTS.transform(geom, transform); + } catch (Exception e) { + UFStatus.getHandler().handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + cache.put(geom, projected); + } + + if (projected != null) { + newGeoms.add(projected); + } + } + return newGeoms; + } + + public void rebuildLayer(Collection currentData, + Stack> undoStack, + Stack> redoStack) { + // pre-build StackFrames so we limit our time in the synchronized block + Collection undoFrames = new ArrayList( + undoStack.capacity()); + for (Collection frame : undoStack) { + undoFrames.add(new StackFrame(frame)); + } + Collection redoFrames = new ArrayList( + redoStack.capacity()); + for (Collection frame : redoStack) { + redoFrames.add(new StackFrame(frame)); + } + + synchronized (currentData) { + this.currentData.geometries.clear(); + this.currentData.geometries.addAll(currentData); + this.undoStack.clear(); + this.undoStack.addAll(undoFrames); + this.redoStack.clear(); + this.redoStack.addAll(redoFrames); + } + } +} diff --git a/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/DrawingToolUIManager.java b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/DrawingToolUIManager.java new file mode 100644 index 0000000000..eb8d6ffb1c --- /dev/null +++ b/cave/com.raytheon.uf.viz.drawing/src/com/raytheon/uf/viz/drawing/DrawingToolUIManager.java @@ -0,0 +1,248 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.drawing; + +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.ImageData; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.uf.viz.drawing.DrawingToolLayer.DrawMode; +import com.raytheon.viz.ui.input.InputAdapter; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * UI manager for a DrawingToolLayer, handles mouse actions for drawing + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 23, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DrawingToolUIManager extends InputAdapter { + + private DrawingToolLayer drawingLayer; + + private Cursor erasor; + + private Cursor pencil; + + /** Normal will never be initialized as null tells SWT to use the default */ + private Cursor normal = null; + + private boolean handlingInput = false; + + protected IDisplayPaneContainer container; + + private Shell currentShell = null; + + public DrawingToolUIManager(DrawingToolLayer drawingLayer, + IDisplayPaneContainer container) { + this.drawingLayer = drawingLayer; + this.container = container; + + VizApp.runAsync(new Runnable() { + @Override + public void run() { + // Create erasor cursor + ImageData data = IconUtil.getImageDescriptor( + Activator.getDefault().getBundle(), "eraser_box.gif") + .getImageData(); + data.alpha = 255; + erasor = new Cursor(Display.getCurrent(), data, 8, 8); + + // Create pencil cursor + data = IconUtil.getImageDescriptor( + Activator.getDefault().getBundle(), "draw.gif") + .getImageData(); + pencil = new Cursor(Display.getCurrent(), data, 1, 15); + + DrawingToolUIManager.this.container + .registerMouseHandler(DrawingToolUIManager.this); + } + }); + } + + public void dispose() { + erasor.dispose(); + pencil.dispose(); + + container.unregisterMouseHandler(this); + if (currentShell != null) { + currentShell.setCursor(null); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.input.InputAdapter#handleMouseExit(org.eclipse.swt + * .widgets.Event) + */ + @Override + public boolean handleMouseExit(Event event) { + if (canTellestrate(event.button)) { + if (currentShell != null) { + clearCursor(currentShell); + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.input.InputAdapter#handleMouseEnter(org.eclipse.swt + * .widgets.Event) + */ + @Override + public boolean handleMouseEnter(Event event) { + if (canTellestrate(event.button)) { + currentShell = ((Control) event.widget).getShell(); + updateCursor(currentShell); + } + return false; + } + + protected void clearCursor(Shell shell) { + if (shell != null) { + shell.setCursor(normal); + } + } + + protected void updateCursor(Shell shell) { + if (shell == null) { + return; + } + switch (drawingLayer.getDrawMode()) { + case DRAW: + if (pencil != null && pencil.isDisposed() == false) { + shell.setCursor(pencil); + } + break; + case ERASE: + if (erasor != null && erasor.isDisposed() == false) { + shell.setCursor(erasor); + } + break; + default: + // normal never gets set and thus will always be null, this is + // the desired behavior + shell.setCursor(normal); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.InputAdapter#handleMouseDown(int, int, + * int) + */ + @Override + public boolean handleMouseDown(int x, int y, int mouseButton) { + if (!canTellestrate(mouseButton)) { + return false; + } + handlingInput = true; + return handleMouseDownMove(x, y, mouseButton); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.InputAdapter#handleMouseDownMove(int, int, + * int) + */ + @Override + public boolean handleMouseDownMove(int x, int y, int mouseButton) { + if (handlingInput == false) { + return false; + } + + Coordinate c = container.translateClick(x, y); + if (c != null) { + drawingLayer.addCoordinate(c); + } + container.refresh(); + return true; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.InputAdapter#handleMouseUp(int, int, int) + */ + @Override + public boolean handleMouseUp(int x, int y, int mouseButton) { + if (handlingInput == false) { + return false; + } + + switch (drawingLayer.getDrawMode()) { + case DRAW: + drawingLayer.doneDrawing(); + break; + case ERASE: + drawingLayer.doneErasing(); + break; + } + container.refresh(); + handlingInput = false; + return true; + } + + protected boolean canTellestrate(int mouseButton) { + return handlingInput == false && mouseButton <= 1 + && drawingLayer.getDrawMode() != DrawMode.NONE; + } + + /** + * handlingInput is the private variable that tells this class whether it + * should be adding points as mouse actions are happening or not. + * + * @param handlingInput + */ + protected void setHandlingInput(boolean handlingInput) { + this.handlingInput = handlingInput; + } + + /** + * @return the currentShell + */ + public Shell getCurrentShell() { + return currentShell; + } +} diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java index 78e41d207a..b08a3eb25c 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/FileTreeView.java @@ -103,6 +103,7 @@ import com.raytheon.uf.viz.core.VizApp; import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.localization.LocalizationEditorInput; import com.raytheon.uf.viz.localization.LocalizationPerspectiveUtils; +import com.raytheon.uf.viz.localization.adapter.LocalizationPerspectiveAdapter; import com.raytheon.uf.viz.localization.filetreeview.FileTreeEntryData; import com.raytheon.uf.viz.localization.filetreeview.LocalizationFileEntryData; import com.raytheon.uf.viz.localization.filetreeview.LocalizationFileGroupData; @@ -540,6 +541,10 @@ public class FileTreeView extends ViewPart implements IPartListener2, data.setRequestedChildren(false); new TreeItem(item, SWT.NONE); expand(expandMap, item); + if (item.getData() instanceof LocalizationFileGroupData + && item.getItemCount() == 0) { + item.dispose(); + } } } else { for (TreeItem child : item.getItems()) { @@ -566,7 +571,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, TreeItem root) { FileTreeEntryData data = (FileTreeEntryData) root.getData(); if (data != null) { - map.put(data, root.getExpanded()); + map.put(data, root.getExpanded() || root.getItemCount() == 0); for (TreeItem item : root.getItems()) { buildExpandedMap(map, item); } @@ -660,7 +665,8 @@ public class FileTreeView extends ViewPart implements IPartListener2, applicationItem.setData(folder); } - FileTreeEntryData treeData = new FileTreeEntryData(pd, pd.getPath()); + FileTreeEntryData treeData = new FileTreeEntryData(pd, pd.getPath(), + true); treeData.setName(pd.getName()); TreeItem dataTypeItem = new TreeItem(applicationItem, SWT.NONE, getInsertionIndex(applicationItem.getItems(), name)); @@ -719,6 +725,9 @@ public class FileTreeView extends ViewPart implements IPartListener2, Tree tree = getTree(); final TreeItem[] selected = tree.getSelection(); + mgr.add(new MenuManager("New", LocalizationPerspectiveAdapter.NEW_ID)); + mgr.add(new Separator()); + if (selected.length > 0) { List dataList = new ArrayList(); @@ -812,6 +821,48 @@ public class FileTreeView extends ViewPart implements IPartListener2, mgr.add(new DeleteAction(getSite().getPage(), fileList .toArray(new LocalizationFile[fileList.size()]))); mgr.add(new Separator()); + } else { + List toDelete = new ArrayList(); + for (TreeItem item : selected) { + int prevSize = toDelete.size(); + if (item.getData() instanceof FileTreeEntryData) { + FileTreeEntryData data = (FileTreeEntryData) item.getData(); + if (data.isRoot() == false) { + if (data instanceof LocalizationFileEntryData) { + toDelete.add(((LocalizationFileEntryData) data) + .getFile()); + } else if (data.isDirectory()) { + String[] parts = LocalizationUtil.splitUnique(data + .getPath()); + String parentDir = parts[0]; + for (int i = 1; i < parts.length - 1; ++i) { + parentDir += IPathManager.SEPARATOR + parts[i]; + } + LocalizationFile[] files = PathManagerFactory + .getPathManager() + .listFiles( + getTreeSearchContexts(data + .getPathData().getType()), + data.getPath(), + new String[] { parts[parts.length - 1] }, + false, false); + toDelete.addAll(Arrays.asList(files)); + } + } + } + if (prevSize == toDelete.size()) { + // This selected item couldn't contribute a file, don't add + // the action to delete any of them + toDelete.clear(); + break; + } + } + + if (toDelete.size() > 0) { + mgr.add(new DeleteAction(getSite().getPage(), toDelete + .toArray(new LocalizationFile[toDelete.size()]))); + mgr.add(new Separator()); + } } // Add the move to item @@ -859,8 +910,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, Object data = selected[0].getData(); if (data instanceof FileTreeEntryData) { FileTreeEntryData fdata = (FileTreeEntryData) data; - if (fdata.isDirectory() - && fdata instanceof LocalizationFileGroupData == false) { + if (fdata.isDirectory()) { // We can import into true directories, not group datas mgr.add(new Separator()); mgr.add(new ImportFileAction(fdata.getPathData().getType(), @@ -947,8 +997,44 @@ public class FileTreeView extends ViewPart implements IPartListener2, IPathManager pathManager = PathManagerFactory.getPathManager(); - // Request for base/site/user + boolean success = false; + List currentList = new ArrayList(); + LocalizationFile[] files = pathManager.listFiles( + getTreeSearchContexts(type), path, filter, false, !recursive); + if (files == null) { + statusHandler.handle(Priority.PROBLEM, + "Error getting list of files"); + } else { + parentItem.removeAll(); + for (LocalizationFile file : files) { + if (checkName + && (file.getName().isEmpty() || data.getPath().equals( + file.getName()))) { + continue; + } + if (file.exists()) { + currentList.add(file); + } + } + + // Sort files using specific ordering... + Collections.sort(currentList, new FileTreeFileComparator()); + + if (data instanceof LocalizationFileGroupData) { + populateGroupDataNode(parentItem, currentList); + } else { + populateDirectoryDataNode(parentItem, currentList); + } + success = true; + } + + return success; + } + + private LocalizationContext[] getTreeSearchContexts(LocalizationType type) { + IPathManager pathManager = PathManagerFactory.getPathManager(); + // Request for base/site/user LocalizationContext[] searchHierarchy = pathManager .getLocalSearchHierarchy(type); List searchContexts = new ArrayList( @@ -987,44 +1073,8 @@ public class FileTreeView extends ViewPart implements IPartListener2, } } } - - boolean success = false; - List currentList = new ArrayList(); - LocalizationFile[] files = pathManager.listFiles(searchContexts - .toArray(new LocalizationContext[searchContexts.size()]), path, - filter, false, !recursive); - if (files == null) { - statusHandler.handle(Priority.PROBLEM, - "Error getting list of files"); - } else { - if (parentItem.getItemCount() == 1 - && parentItem.getItems()[0].getData() == null) { - parentItem.removeAll(); - } - - for (LocalizationFile file : files) { - if (checkName - && (file.getName().isEmpty() || data.getPath().equals( - file.getName()))) { - continue; - } - if (file.exists()) { - currentList.add(file); - } - } - - // Sort files using specific ordering... - Collections.sort(currentList, new FileTreeFileComparator()); - - if (data instanceof LocalizationFileGroupData) { - populateGroupDataNode(parentItem, currentList); - } else { - populateDirectoryDataNode(parentItem, currentList); - } - success = true; - } - - return success; + return searchContexts.toArray(new LocalizationContext[searchContexts + .size()]); } private void populateDirectoryDataNode(TreeItem parentItem, @@ -1061,24 +1111,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, TreeItem[] children = parentItem.getItems(); for (TreeItem child : children) { String path = ((FileTreeEntryData) child.getData()).getPath(); - if (processedPaths.contains(path) == false) { - // File no longer exists, delete - Object objData = child.getData(); - if (objData instanceof FileTreeEntryData) { - IResource rsc = ((FileTreeEntryData) objData).getResource(); - if (rsc != null) { - try { - rsc.delete(true, null); - } catch (CoreException e) { - statusHandler.handle( - Priority.PROBLEM, - "Error deleting resource: " - + e.getLocalizedMessage(), e); - } - } - } - child.dispose(); - } else if (processedFiles.containsKey(path)) { + if (processedFiles.containsKey(path)) { populateGroupDataNode(child, processedFiles.get(path)); } } @@ -1267,103 +1300,77 @@ public class FileTreeView extends ViewPart implements IPartListener2, } } - /** - * Finds the first TreeItem in the tree which matches the localization file - * (minus level). If file is a directory, will return TreeItem which - * corresponds to that directory - * - * @param file - * @param nullIfNotFound - * if true, will return null when file is not found and - * populating the node would be required - * @return - */ - private TreeItem find(LocalizationFile file, boolean nullIfNotFound) { - return find(file.getName(), file.getContext(), nullIfNotFound); + private TreeItem find(LocalizationFile file, boolean populateToFind, + boolean nearestParent) { + return find(file.getName(), file.getContext(), populateToFind, + nearestParent); } private TreeItem find(String path, LocalizationContext context, - boolean nullIfNotFound) { - TreeItem rval = null; + boolean populateToFind, boolean nearestParent) { Tree tree = getTree(); TreeItem[] items = tree.getItems(); - String[] parts = LocalizationUtil.splitUnique(path); for (TreeItem item : items) { - TreeItem found = find(item, context, parts, 0, nullIfNotFound); - if (found != null) { - rval = found; - break; - } - } - return rval; - } + // item is an Application level node, check child, find will return + // null if incorrect path, otherwise it will return closest ancestor + // of the item we are looking for. If null, keep looking, otherwise + // check the search method + for (TreeItem basePathItem : item.getItems()) { + TreeItem found = find(basePathItem, context, path, + populateToFind); + if (found != null) { + TreeItem rval = null; + if (nearestParent) { + rval = found; + } - /** - * Finds the first TreeItem in the application tree node which contains the - * localization file. If file is a directory, will return TreeItem which - * corresponds to that directory - * - * @param item - * @param file - * @return - */ - private TreeItem find(TreeItem item, LocalizationContext ctx, - String[] parts, int index, boolean nullIfNotFound) { - if ((item.getData() != null) - && (item.getData() instanceof FileTreeEntryData)) { - FileTreeEntryData itemData = (FileTreeEntryData) item.getData(); - if (itemData.hasRequestedChildren() == false) { - if (nullIfNotFound) { - return null; - } else { - populateNode(item); + FileTreeEntryData foundData = (FileTreeEntryData) found + .getData(); + if (foundData.getPath().equals(path)) { + // Found this item, check if group data + if (foundData instanceof LocalizationFileGroupData) { + // Check for context matching + for (TreeItem fileItem : found.getItems()) { + LocalizationFileEntryData fileData = (LocalizationFileEntryData) fileItem + .getData(); + if (fileData.getFile().getContext() + .equals(context)) { + rval = fileItem; + break; + } + } + } else { + rval = found; + } + } + return rval; } } } + return null; + } - if (index == parts.length) { - if (item.getData() instanceof LocalizationFileGroupData) { - TreeItem[] children = item.getItems(); - for (TreeItem child : children) { - if (((LocalizationFileEntryData) child.getData()).getFile() - .getContext().equals(ctx)) { - return child; + private TreeItem find(TreeItem item, LocalizationContext ctx, String path, + boolean populateToFind) { + FileTreeEntryData data = (FileTreeEntryData) item.getData(); + String itemPath = data.getPath(); + if (path.startsWith(itemPath)) { + if (path.equals(itemPath) + || (data.hasRequestedChildren() == false && !populateToFind)) { + return item; + } else { + if (data.hasRequestedChildren() == false) { + populateNode(item); + } + for (TreeItem child : item.getItems()) { + TreeItem rval = find(child, ctx, path, populateToFind); + if (rval != null) { + return rval; } } } return item; } - - TreeItem[] children = item.getItems(); - for (TreeItem child : children) { - FileTreeEntryData data = (FileTreeEntryData) child.getData(); - PathData pd = data.getPathData(); - if (pd.getType() == ctx.getLocalizationType()) { - // same type, check PathData path - String[] childParts = new String[] { data.getName() }; - if ((item.getData() instanceof FileTreeEntryData) == false) { - childParts = LocalizationUtil.splitUnique(data.getPath()); - } - boolean equal = true; - for (int i = 0; (i < childParts.length) && equal; ++i) { - if ((i + index >= parts.length) - || (parts[i + index].equals(childParts[i]) == false)) { - equal = false; - } - } - - if (equal) { - if (parts.length == (index + childParts.length)) { - return child; - } else { - TreeItem found = find(child, ctx, parts, index - + childParts.length, nullIfNotFound); - return found != null ? found : child; - } - } - } - } - return null; } @@ -1460,12 +1467,12 @@ public class FileTreeView extends ViewPart implements IPartListener2, String filePath = message.getFileName(); IPathManager pathManager = PathManagerFactory.getPathManager(); + final FileChangeType type = message.getChangeType(); final LocalizationFile file = pathManager.getLocalizationFile(context, filePath); - if ((file.exists() == false && (message.getChangeType() == FileChangeType.ADDED || message - .getChangeType() == FileChangeType.UPDATED)) - || (file.exists() && message.getChangeType() == FileChangeType.DELETED)) { + if ((file.exists() == false && (type == FileChangeType.ADDED || type == FileChangeType.UPDATED)) + || (file.exists() && type == FileChangeType.DELETED)) { System.out.println("Got weird state in update for " + file + ": exists=" + file.exists() + ", changeType=" + message.getChangeType()); @@ -1475,8 +1482,15 @@ public class FileTreeView extends ViewPart implements IPartListener2, VizApp.runAsync(new Runnable() { @Override public void run() { - TreeItem toRefresh = find(file, true); + // Only get closest parent if file added + TreeItem toRefresh = find(file, false, + type == FileChangeType.ADDED); if (toRefresh != null) { + if (type == FileChangeType.DELETED) { + // If deleted, we found the actual item that was + // deleted, we should refresh it's parent + toRefresh = toRefresh.getParentItem(); + } refresh(toRefresh); } } @@ -1607,22 +1621,9 @@ public class FileTreeView extends ViewPart implements IPartListener2, */ @Override public void selectFile(LocalizationFile file) { - TreeItem item = find(file, false); + TreeItem item = find(file, true, false); if (item != null) { - FileTreeEntryData data = (FileTreeEntryData) item.getData(); - if (data.getPath().equals(file.getName())) { - if (data instanceof LocalizationFileGroupData) { - for (TreeItem child : item.getItems()) { - LocalizationFileEntryData lfed = (LocalizationFileEntryData) child - .getData(); - if (lfed != null && lfed.getFile().equals(file)) { - getTree().setSelection(child); - return; - } - } - } - getTree().setSelection(item); - } + getTree().setSelection(item); } } @@ -1635,7 +1636,7 @@ public class FileTreeView extends ViewPart implements IPartListener2, @Override public void refresh(LocalizationFile file) { if (file != null) { - TreeItem item = find(file, false); + TreeItem item = find(file, false, false); if (item != null) { refresh(item); } @@ -1651,21 +1652,15 @@ public class FileTreeView extends ViewPart implements IPartListener2, @Override public void openFile(LocalizationFile file) { IWorkbenchPage page = this.getSite().getPage(); - TreeItem item = find(file, true); + TreeItem item = find(file, true, false); if (item != null) { - LocalizationFileGroupData groupData = (LocalizationFileGroupData) item + LocalizationFileEntryData fileData = (LocalizationFileEntryData) item .getData(); - IFile data = null; - for (LocalizationFileEntryData child : groupData.getChildrenData()) { - if (file.equals(child.getFile())) { - data = child.getResource(); - break; - } - } - if (data != null) { - LocalizationPerspectiveUtils.openInEditor(page, - new LocalizationEditorInput(file, data)); - } + LocalizationPerspectiveUtils.openInEditor(page, + new LocalizationEditorInput(file, fileData.getResource())); + } else { + statusHandler.handle(Priority.PROBLEM, "Unable to find " + file + + " in view to open"); } } diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/LocalizationFileDragNDropSource.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/LocalizationFileDragNDropSource.java index ea7a4dccea..ce78272941 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/LocalizationFileDragNDropSource.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/LocalizationFileDragNDropSource.java @@ -81,9 +81,11 @@ public class LocalizationFileDragNDropSource extends ViewerDropAdapter this.view = view; } - LocalizationFile potentialDelete = null; + private LocalizationFile toCopy = null; - LocalizationFile toDelete = null; + private LocalizationFile potentialDelete = null; + + private LocalizationFile toDelete = null; // Drag methods @@ -99,7 +101,7 @@ public class LocalizationFileDragNDropSource extends ViewerDropAdapter event.doit = file.getContext().getLocalizationLevel() .isSystemLevel() == false; event.image = selected[0].getImage(); - potentialDelete = file; + toCopy = potentialDelete = file; } } @@ -121,7 +123,7 @@ public class LocalizationFileDragNDropSource extends ViewerDropAdapter @Override public void dragSetData(DragSourceEvent event) { - event.data = new String[] { potentialDelete.getFile().getAbsolutePath() }; + event.data = new String[] { toCopy.getFile().getAbsolutePath() }; } // Drop methods @@ -174,6 +176,9 @@ public class LocalizationFileDragNDropSource extends ViewerDropAdapter FileTreeEntryData data = (FileTreeEntryData) target; if (data instanceof LocalizationFileEntryData == false && data instanceof LocalizationFileGroupData == false) { + if (operation == DND.DROP_COPY) { + potentialDelete = null; + } return true; } } diff --git a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/RenameAction.java b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/RenameAction.java index 03e1a22214..a492771fd8 100644 --- a/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/RenameAction.java +++ b/cave/com.raytheon.uf.viz.localization.perspective/src/com/raytheon/uf/viz/localization/perspective/view/actions/RenameAction.java @@ -19,6 +19,8 @@ **/ package com.raytheon.uf.viz.localization.perspective.view.actions; +import java.util.regex.Pattern; + import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.dialogs.IInputValidator; @@ -60,6 +62,46 @@ import com.raytheon.viz.ui.VizWorkbenchManager; public class RenameAction extends Action { + public static class NewFileInputValidator implements IInputValidator { + + private static final String VALID_FILE_REGEX = "^[a-zA-Z0-9_]+[a-zA-Z0-9_\\-.]*$"; + + private static final Pattern VALID_FILE_PATTERN = Pattern + .compile(VALID_FILE_REGEX); + + private String initialValue; + + public NewFileInputValidator(String initialValue) { + this.initialValue = initialValue; + } + + @Override + public String isValid(String newText) { + if (initialValue != null && initialValue.equals(newText.trim())) { + return "File name is not different"; + } else if (newText.trim().isEmpty()) { + return "New name must not be empty"; + } else { + String[] parts = newText.split("[" + IPathManager.SEPARATOR + + "]"); + if (VALID_FILE_PATTERN.matcher(parts[parts.length - 1]) + .matches() == false) { + return "File name must only contain " + + FileUtil.VALID_FILENAME_CHARS; + } + for (int i = 0; i < parts.length - 1; ++i) { + if (parts[i].isEmpty() == false + && VALID_FILE_PATTERN.matcher(parts[i]).matches() == false) { + return "Directory path: " + parts[i] + + " must only contain " + + FileUtil.VALID_FILENAME_CHARS; + } + } + } + return null; + } + } + private LocalizationFile file; private ILocalizationService service; @@ -94,21 +136,7 @@ public class RenameAction extends Action { boolean done = false; while (!canceled && !done) { InputDialog dialog = new InputDialog(parent, "Rename file", - "File name:", name, new IInputValidator() { - - @Override - public String isValid(String newText) { - if (name.equals(newText.trim())) { - return "File name is not different"; - } else if (!FileUtil.isValidFilename(newText)) { - return "New name may only contain " - + FileUtil.VALID_FILENAME_CHARS; - } else if ("".equals(newText.trim())) { - return "New name must not be empty"; - } - return null; - } - }); + "File name:", name, new NewFileInputValidator(name)); if (InputDialog.OK == dialog.open()) { pathParts[pathParts.length - 1] = dialog.getValue(); String newPath = pathParts[0]; diff --git a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java index 9398040477..49bd423cf9 100644 --- a/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java +++ b/cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java @@ -150,6 +150,7 @@ import com.vividsolutions.jts.geom.Point; * 29 June, 2009 2521 dhladky Initial creation * 11 Apr. 2012 DR 14522 gzhang Fixing invalid thread error. * 31 July 2012 14517 mpduff Fix for blanking map on update. + * 14 Sep 2012 1048 njensen Code cleanup * * * @@ -161,6 +162,10 @@ public class FFMPResource extends AbstractVizResource implements IResourceDataChanged, IFFMPResourceListener, FFMPListener, FFMPLoadListener { + + // TODO move ALL constant to common plugin + private static final String ALL = "ALL"; + private static final transient IUFStatusHandler statusHandler = UFStatus .getHandler(FFMPResource.class); @@ -375,7 +380,7 @@ public class FFMPResource extends /** ordered list of times **/ private ArrayList timeOrderedKeys = new ArrayList(); - + private boolean toKeysInitialized = false; /** force utility **/ @@ -424,22 +429,19 @@ public class FFMPResource extends .equals(getResourceData().sourceName)) { // go back an extra time step Date previousMostRecentTime = null; - if (getTimeOrderedKeys().size() >= 2) { - previousMostRecentTime = getTimeOrderedKeys().get( - getTimeOrderedKeys().size() - 2); - } else if (getTimeOrderedKeys().size() >= 1) { - previousMostRecentTime = getTimeOrderedKeys().get( - getTimeOrderedKeys().size() - 1); + List tok = getTimeOrderedKeys(); + if (tok.size() >= 2) { + previousMostRecentTime = tok.get(tok.size() - 2); } else { - previousMostRecentTime = getTimeOrderedKeys().get(0); + previousMostRecentTime = tok.get(0); } updateTimeOrderedkeys(ffmpRec.getDataTime().getRefTime()); - + if (getResourceData().tableLoad) { setTableTime(); } - + setRecord(ffmpRec); statusHandler.handle(Priority.INFO, "Updating : Previous: " @@ -476,17 +478,7 @@ public class FFMPResource extends purge(ffmpRec.getDataTime().getRefTime()); } - qpeRecord = null; - isNewQpe = true; - isNewRate = true; - rateRecord = null; - isNewRate = true; - virtualRecord = null; - isNewVirtual = true; - guidRecord = null; - isNewGuid = true; - qpfRecord = null; - isNewQpf = true; + resetRecords(); } } catch (VizException ve) { @@ -503,6 +495,24 @@ public class FFMPResource extends refresh(); } + /** + * Resets the records to null and sets the boolean values relating to if the + * data is new to true + */ + private void resetRecords() { + isNewQpe = true; + isNewRate = true; + isNewVirtual = true; + isNewGuid = true; + isNewQpf = true; + + qpeRecord = null; + rateRecord = null; + virtualRecord = null; + guidRecord = null; + qpfRecord = null; + } + @Override public void refresh() { if (!isAutoRefresh) { @@ -573,13 +583,14 @@ public class FFMPResource extends Date recentTime, boolean aggregate) throws VizException { FFMPBasin basin = null; + String huc = null; if (aggregate) { - basin = getRecord(bfield, recentTime).getBasinData(getHuc()) - .getBasins().get(key); + huc = getHuc(); } else { - basin = getRecord(bfield, recentTime).getBasinData("ALL") - .getBasins().get(key); + huc = ALL; } + basin = getRecord(bfield, recentTime).getBasinData(huc).getBasins() + .get(key); return basin; } @@ -598,7 +609,7 @@ public class FFMPResource extends double value = Double.NaN; if (centeredAggregationKey != null) { - if (getHuc().equals("ALL")) { + if (getHuc().equals(ALL)) { value = getBasinValue(key, recentTime, false); return getColorUtil().colorByValue(value); } else { @@ -653,12 +664,12 @@ public class FFMPResource extends break; } case RATE: { - value = getRateRecord(recentTime).getBasinData("ALL") + value = getRateRecord(recentTime).getBasinData(ALL) .getMaxValue(pfafs, recentTime); break; } case QPF: { - value = getQpfRecord(recentTime).getBasinData("ALL") + value = getQpfRecord(recentTime).getBasinData(ALL) .getAverageMaxValue(pfafs, recentTime, getQpfSourceExpiration()); break; @@ -667,21 +678,17 @@ public class FFMPResource extends long fips = monitor.getTemplates(getSiteKey()) .getCountyFipsByPfaf(pfafs.get(0)); - value = getGuidanceRecord().getBasinData("ALL") + value = getGuidanceRecord().getBasinData(ALL) .getMaxGuidanceValue(pfafs, getGuidanceInterpolation(getFFGName()), getGuidSourceExpiration(), fips); break; } case QPE: { - value = getQpeRecord().getBasinData("ALL") - .getAccumMaxValue( - pfafs, - recentTime, - getTableTime(), - getQpeSourceExpiration(), - getResourceData().getPrimarySourceXML() - .isRate()); + value = getQpeRecord().getBasinData(ALL).getAccumMaxValue( + pfafs, recentTime, getTableTime(), + getQpeSourceExpiration(), + getResourceData().getPrimarySourceXML().isRate()); break; } } @@ -781,12 +788,12 @@ public class FFMPResource extends boolean forced = forceUtil.isForced(); if ((forcedPfafs.size() > 0) && forced) { // Recalculate the guidance using the forced value(s) - value = guidRecord.getBasinData("ALL").getAverageGuidanceValue( + value = guidRecord.getBasinData(ALL).getAverageGuidanceValue( pfafList, this.getGuidanceInterpolation(getFFGName()), new Float(value), forcedPfafs, getGuidSourceExpiration()); } else if (forcedPfafs.size() > 0) { - value = guidRecord.getBasinData("ALL").getAverageGuidanceValue( + value = guidRecord.getBasinData(ALL).getAverageGuidanceValue( pfafList, this.getGuidanceInterpolation(getFFGName()), Float.NaN, forcedPfafs, getGuidSourceExpiration()); } @@ -850,6 +857,21 @@ public class FFMPResource extends return prefix.toString(); } + /** + * Returns the ALL huc if worst case, otherwise the huc + * + * @return + */ + private String getHucIfWorstCase() { + String huc = null; + if (isWorstCase()) { + huc = ALL; + } else { + huc = getHuc(); + } + return huc; + } + /** * Gets the record currently used * @@ -859,19 +881,11 @@ public class FFMPResource extends if ((rateRecord == null) && isNewRate) { try { - - if (isWorstCase()) { - rateRecord = monitor.getRateRecord(getProduct(), - getSiteKey(), getDataKey(), getPrimarySource(), - recentTime, "ALL", false); - } else { - rateRecord = monitor.getRateRecord(getProduct(), - getSiteKey(), getDataKey(), getPrimarySource(), - recentTime, getHuc(), false); - } - + String huc = getHucIfWorstCase(); + rateRecord = monitor.getRateRecord(getProduct(), getSiteKey(), + getDataKey(), getPrimarySource(), recentTime, huc, + false); isNewRate = false; - } catch (Exception e) { e.printStackTrace(); } @@ -887,18 +901,10 @@ public class FFMPResource extends public FFMPCacheRecord getQpeRecord() { try { if ((qpeRecord == null) && (getTableTime() != null) && isNewQpe) { - - if (isWorstCase()) { - qpeRecord = monitor.getQPERecord(getProduct(), - getSiteKey(), getDataKey(), getPrimarySource(), - getTableTime(), "ALL", false); - - } else { - qpeRecord = monitor.getQPERecord(getProduct(), - getSiteKey(), getDataKey(), getPrimarySource(), - getTableTime(), getHuc(), false); - } - + String huc = getHucIfWorstCase(); + qpeRecord = monitor.getQPERecord(getProduct(), getSiteKey(), + getDataKey(), getPrimarySource(), getTableTime(), huc, + false); isNewQpe = false; } } catch (Exception e) { @@ -930,16 +936,9 @@ public class FFMPResource extends isStandAlone = true; } - if (isWorstCase()) { - guidRecord = monitor - .getGuidanceRecord(getProduct(), getSiteKey(), - sourceName, date, "ALL", isStandAlone); - } else { - guidRecord = monitor.getGuidanceRecord(getProduct(), - getSiteKey(), sourceName, date, getHuc(), - isStandAlone); - } - + String huc = getHucIfWorstCase(); + guidRecord = monitor.getGuidanceRecord(getProduct(), + getSiteKey(), sourceName, date, huc, isStandAlone); isNewGuid = false; } @@ -968,15 +967,9 @@ public class FFMPResource extends } } - qpfRecord = monitor - .getQPFRecord(getProduct(), getSiteKey(), getDataKey(), - getPrimarySource(), date, getHuc(), false); - if (isWorstCase()) { - qpfRecord = monitor.getQPFRecord(getProduct(), - getSiteKey(), getDataKey(), getPrimarySource(), - date, "ALL", false); - } - + String huc = getHucIfWorstCase(); + qpfRecord = monitor.getQPFRecord(getProduct(), getSiteKey(), + getDataKey(), getPrimarySource(), date, huc, false); isNewQpf = false; } } catch (Exception e) { @@ -996,7 +989,7 @@ public class FFMPResource extends if ((virtualRecord == null) && isNewVirtual) { virtualRecord = monitor.getVirtualRecord(getProduct(), getSiteKey(), getDataKey(), getPrimarySource(), - getTableTime(), "ALL", false); + getTableTime(), ALL, false); isNewVirtual = false; } @@ -1191,7 +1184,8 @@ public class FFMPResource extends FFMPDrawable drawable = null; if (paintTime != null) { - if (loader != null && !loader.isDone && loader.loadType == LOADER_TYPE.GENERAL) { + if (loader != null && !loader.isDone + && loader.loadType == LOADER_TYPE.GENERAL) { return; } if (!drawables.containsKey(paintTime)) { @@ -1201,7 +1195,7 @@ public class FFMPResource extends } else { // we found it! drawable = drawables.get(paintTime); -// System.out.println("Found the drawable"); + // System.out.println("Found the drawable"); if (!paintTime.equals(drawable.getTime())) { drawable.setDirty(true); @@ -1223,7 +1217,8 @@ public class FFMPResource extends && !paintTime.getRefTime().equals(getMostRecentTime())) { setMostRecentTime(paintTime.getRefTime()); setTableTime(); -// if (isLinkToFrame && loader != null && loader.loadType != LOADER_TYPE.GENERAL) { + // if (isLinkToFrame && loader != null && loader.loadType != + // LOADER_TYPE.GENERAL) { if (isLinkToFrame) { updateDialog(); } @@ -1246,6 +1241,7 @@ public class FFMPResource extends lastExtent = expandedExtent; } + boolean isAllHuc = getHuc().equals(ALL); for (DomainXML domain : getDomains()) { String cwa = domain.getCwa(); if (isShaded) { @@ -1295,9 +1291,8 @@ public class FFMPResource extends } if ((lowestCenter == ZOOM.AGGREGATE) - || (lowestCenter == ZOOM.BASIN) - || getHuc().equals("ALL") || this.isBasinToggle() - || isSmallBasins) { + || (lowestCenter == ZOOM.BASIN) || isAllHuc + || this.isBasinToggle() || isSmallBasins) { if (isSmallBasins && this.isBasinToggle()) { if ((smallBasinOverlayShape != null) @@ -1334,31 +1329,29 @@ public class FFMPResource extends if (centeredAggregationKey != null) { vgbDrawables.clear(); // create pixelCoverages for the VGB's - if (lowestCenter == FFMPRecord.ZOOM.AGGREGATE) { - if (getHuc().equals("ALL")) { - for (DomainXML domain : getDomains()) { - for (Long pfaf : monitor + if (isAllHuc) { + for (DomainXML domain : getDomains()) { + for (Long pfaf : monitor + .getTemplates(getSiteKey()) + .getMap(getSiteKey(), domain.getCwa(), getHuc()) + .keySet()) { + ArrayList fvgmdList = monitor .getTemplates(getSiteKey()) - .getMap(getSiteKey(), domain.getCwa(), - getHuc()).keySet()) { - ArrayList fvgmdList = monitor - .getTemplates(getSiteKey()) - .getVirtualGageBasinMetaData( - getSiteKey(), domain.getCwa(), - pfaf); - if (fvgmdList != null) { - for (FFMPVirtualGageBasinMetaData fvgmd : fvgmdList) { - vgbDrawables.put( - fvgmd.getLid(), - getPixelCoverage( - fvgmd.getCoordinate(), - paintProps)); - } + .getVirtualGageBasinMetaData(getSiteKey(), + domain.getCwa(), pfaf); + if (fvgmdList != null) { + for (FFMPVirtualGageBasinMetaData fvgmd : fvgmdList) { + vgbDrawables.put( + fvgmd.getLid(), + getPixelCoverage( + fvgmd.getCoordinate(), + paintProps)); } } } - - } else { + } + } else { + if (lowestCenter == FFMPRecord.ZOOM.AGGREGATE) { for (Long pfaf : monitor.getTemplates(getSiteKey()) .getAllAggregatePfafs(centeredAggregationKey, getHuc())) { @@ -1376,30 +1369,6 @@ public class FFMPResource extends } } } - } - } else { - if (getHuc().equals("ALL")) { - for (DomainXML domain : getDomains()) { - for (Long pfaf : monitor - .getTemplates(getSiteKey()) - .getMap(getSiteKey(), domain.getCwa(), - getHuc()).keySet()) { - ArrayList fvgmdList = monitor - .getTemplates(getSiteKey()) - .getVirtualGageBasinMetaData( - getSiteKey(), domain.getCwa(), - pfaf); - if (fvgmdList != null) { - for (FFMPVirtualGageBasinMetaData fvgmd : fvgmdList) { - vgbDrawables.put( - fvgmd.getLid(), - getPixelCoverage( - fvgmd.getCoordinate(), - paintProps)); - } - } - } - } } else { for (DomainXML domain : getDomains()) { for (Entry entry : monitor @@ -1604,7 +1573,7 @@ public class FFMPResource extends try { FFMPBasinMetaData metaBasin = monitor.getTemplates(getSiteKey()) .findBasinByLatLon(getSiteKey(), coord.asLatLon()); - if (getHuc().equals("ALL") || centeredAggregationKey != null) { + if (getHuc().equals(ALL) || centeredAggregationKey != null) { pfaf = metaBasin.getPfaf(); if (isMaintainLayer) { pfaf = monitor.getTemplates(getSiteKey()) @@ -1717,10 +1686,11 @@ public class FFMPResource extends int mapWidth = getDescriptor().getMapWidth() / 1000; FFMPTemplates templates = monitor.getTemplates(getSiteKey()); String huc = getHuc(); + boolean isAllHuc = huc.equals(ALL); if (centeredAggregationKey == null) { centeredAggregationKey = fz.getKey(); - if (!"ALL".equals(huc)) { + if (!isAllHuc) { center = templates.findAggregationCenter( (Long) centeredAggregationKey, getSiteKey(), huc); @@ -1732,7 +1702,7 @@ public class FFMPResource extends getDescriptor().getRenderableDisplay().getExtent().reset(); float zoomLevel = 0.0f; - if (!getHuc().equals("ALL")) { + if (!isAllHuc) { if (lowestCenter == FFMPRecord.ZOOM.WFO) { clearAllHuc(); } @@ -1749,7 +1719,7 @@ public class FFMPResource extends } else if (!centeredAggregationKey.equals(fz.getKey())) { centeredAggregationKey = fz.getKey(); if (lowestCenter == FFMPRecord.ZOOM.WFO) { - if (!getHuc().equals("ALL")) { + if (!isAllHuc) { centeredAggregationKey = fz.getKey(); center = templates.findAggregationCenter( (Long) centeredAggregationKey, getSiteKey(), @@ -1762,7 +1732,7 @@ public class FFMPResource extends getDescriptor().getRenderableDisplay().getExtent().reset(); float zoomLevel = 0.0f; - if (!getHuc().equals("ALL")) { + if (!isAllHuc) { clearTables(); lowestCenter = FFMPRecord.ZOOM.AGGREGATE; zoomLevel = (float) AGGREGATE_ZOOM / mapWidth; @@ -1798,8 +1768,7 @@ public class FFMPResource extends } // stops the annoying wait cursor every time you re-center - if (getHuc().equals("ALL") - || (lowestCenter == FFMPRecord.ZOOM.BASIN)) { + if (isAllHuc || (lowestCenter == FFMPRecord.ZOOM.BASIN)) { basinTableDlg.getShell().setCursor(null); } } @@ -1874,12 +1843,11 @@ public class FFMPResource extends ArrayList guids = null; if ((getQpeRecord() != null) && (getGuidanceRecord() != null)) { - qpes = getQpeRecord().getBasinData("ALL") - .getAccumValues(pfafs, getTableTime(), - recentTime, getQpeSourceExpiration(), - isRate()); + qpes = getQpeRecord().getBasinData(ALL).getAccumValues( + pfafs, getTableTime(), recentTime, + getQpeSourceExpiration(), isRate()); - guids = getGuidanceRecord().getBasinData("ALL") + guids = getGuidanceRecord().getBasinData(ALL) .getGuidanceValues(pfafs, getGuidanceInterpolation(getFFGName()), getGuidSourceExpiration()); @@ -1911,14 +1879,14 @@ public class FFMPResource extends } else { if ((getQpeRecord() != null) && (getGuidanceRecord() != null)) { qpe = getQpeRecord() - .getBasinData("ALL") + .getBasinData(ALL) .get(key) .getAccumValue(getTableTime(), recentTime, getQpeSourceExpiration(), isRate()); guid = getGuidanceValue( (FFMPGuidanceBasin) getGuidanceRecord() - .getBasinData("ALL").get(key), recentTime, + .getBasinData(ALL).get(key), recentTime, getFFGName()); guid = forceValue(pfafs, getBasin(key, getField(), recentTime, aggregate), @@ -1952,13 +1920,12 @@ public class FFMPResource extends ArrayList qpes = null; ArrayList guids = null; if (getQpeRecord() != null) { - qpes = getQpeRecord().getBasinData("ALL") - .getAccumValues(pfafs, getTableTime(), - recentTime, getQpeSourceExpiration(), - isRate()); + qpes = getQpeRecord().getBasinData(ALL).getAccumValues( + pfafs, getTableTime(), recentTime, + getQpeSourceExpiration(), isRate()); } if (getGuidanceRecord() != null) { - guids = getGuidanceRecord().getBasinData("ALL") + guids = getGuidanceRecord().getBasinData(ALL) .getGuidanceValues(pfafs, getGuidanceInterpolation(getFFGName()), getGuidSourceExpiration()); @@ -1988,13 +1955,13 @@ public class FFMPResource extends } else { if ((getQpeRecord() != null) && (getGuidanceRecord() != null)) { qpe = getQpeRecord() - .getBasinData("ALL") + .getBasinData(ALL) .get(key) .getAccumValue(getTableTime(), recentTime, getQpeSourceExpiration(), isRate()); guid = getGuidanceValue( (FFMPGuidanceBasin) getGuidanceRecord() - .getBasinData("ALL").get(key), recentTime, + .getBasinData(ALL).get(key), recentTime, getFFGName()); ratio = FFMPUtils.getRatioValue(qpe, guid); } @@ -2067,7 +2034,7 @@ public class FFMPResource extends public void clearAllHuc() { if (drawables != null) { for (Entry entry : drawables.entrySet()) { - entry.getValue().removeTable("ALL"); + entry.getValue().removeTable(ALL); } } } @@ -2219,7 +2186,7 @@ public class FFMPResource extends for (DomainXML domain : getDomains()) { try { Map map = hucGeomFactory.getGeometries( - templates, getSiteKey(), domain.getCwa(), "ALL"); + templates, getSiteKey(), domain.getCwa(), ALL); if (map.containsKey(pfaf)) { center = map.get(pfaf).getCentroid().getCoordinate(); @@ -2359,40 +2326,40 @@ public class FFMPResource extends private float getVGBValue(Long pfaf, Date recentTime) { float value = 0.0f; if (getField() == FIELDS.RATE) { - value = getVirtualRecord().getBasinsMap().get("ALL").get(pfaf) + value = getVirtualRecord().getBasinsMap().get(ALL).get(pfaf) .getValue(recentTime); } else if (getField() == FIELDS.QPE) { value = getVirtualRecord() .getBasinsMap() - .get("ALL") + .get(ALL) .get(pfaf) .getAccumValue(getTableTime(), getMostRecentTime(), getQpeSourceExpiration(), isRate()); } else if (getField() == FIELDS.RATIO) { float qpe = getVirtualRecord() .getBasinsMap() - .get("ALL") + .get(ALL) .get(pfaf) .getAccumValue(getTableTime(), getMostRecentTime(), getQpeSourceExpiration(), isRate()); float guidance = getGuidanceValue( ((FFMPGuidanceBasin) getGuidanceRecord().getBasinsMap() - .get("ALL").get(pfaf)), recentTime, getFFGName()); + .get(ALL).get(pfaf)), recentTime, getFFGName()); value = FFMPUtils.getRatioValue(qpe, guidance); } else if (getField() == FIELDS.DIFF) { float qpe = getVirtualRecord() .getBasinsMap() - .get("ALL") + .get(ALL) .get(pfaf) .getAccumValue(getTableTime(), getMostRecentTime(), getQpeSourceExpiration(), isRate()); float guidance = getGuidanceValue( ((FFMPGuidanceBasin) getGuidanceRecord().getBasinsMap() - .get("ALL").get(pfaf)), recentTime, getFFGName()); + .get(ALL).get(pfaf)), recentTime, getFFGName()); value = FFMPUtils.getDiffValue(qpe, guidance); } else if (getField() == FIELDS.GUIDANCE) { value = getGuidanceValue(((FFMPGuidanceBasin) getGuidanceRecord() - .getBasinsMap().get("ALL").get(pfaf)), recentTime, + .getBasinsMap().get(ALL).get(pfaf)), recentTime, getFFGName()); } return value; @@ -2542,6 +2509,7 @@ public class FFMPResource extends .getTemplates(getSiteKey()); String phuc = getHuc(); + boolean isAllPhuc = phuc.equals(ALL); FIELDS field = getField(); if (getResourceData().tableLoad) { @@ -2563,16 +2531,7 @@ public class FFMPResource extends .isWorstCase())); if (globalRegen) { - rateRecord = null; - isNewRate = true; - qpfRecord = null; - isNewQpf = true; - qpeRecord = null; - isNewQpe = true; - guidRecord = null; - isNewGuid = true; - virtualRecord = null; - isNewVirtual = true; + resetRecords(); } for (DomainXML domain : getDomains()) { @@ -2598,7 +2557,7 @@ public class FFMPResource extends pfafsToProcess = cwaPfafs; } else { // center selected, determine center key - if (!phuc.equals("ALL")) { + if (!isAllPhuc) { if (centeredAggregationKey instanceof String) { if (lowestCenter != ZOOM.BASIN) { @@ -2661,7 +2620,7 @@ public class FFMPResource extends HashMap colorMap = new HashMap(); String shadedHuc = null; - if (!phuc.equals("ALL")) { + if (!isAllPhuc) { Map geomMap = hucGeomFactory .getGeometries(templates, @@ -2670,28 +2629,19 @@ public class FFMPResource extends for (Long pfaf : pfafsToProcess) { if (!isMaintainLayer() && isParent() - && !"ALL".equals(phuc) && pfaf.equals(centeredAggr)) { // add centered aggr to shape Collection allPfafs = null; - if (!"ALL".equals(phuc)) { - - if (isParent()) { - allPfafs = templates - .getMap(getSiteKey(), - cwa, "ALL") - .keySet(); - } else { - allPfafs = (List) (templates - .getMap(getSiteKey(), - cwa, phuc) - .get(centeredAggr)); - } + if (isParent()) { + allPfafs = templates.getMap( + getSiteKey(), cwa, ALL) + .keySet(); } else { - allPfafs = new ArrayList( - 1); - allPfafs.add(centeredAggr); + allPfafs = (List) (templates + .getMap(getSiteKey(), + cwa, phuc) + .get(centeredAggr)); } if (allPfafs != null) { @@ -2699,29 +2649,29 @@ public class FFMPResource extends .getGeometries( templates, getSiteKey(), - cwa, "ALL"); + cwa, ALL); IColormapShadedShape shape = shadedShapes - .getShape(cwa, "ALL", + .getShape(cwa, ALL, req.target, descriptor); - shadedHuc = "ALL"; + shadedHuc = ALL; for (Long allPfaf : allPfafs) { generateShapes(templates, - "ALL", allPfaf, + ALL, allPfaf, allGeomMap, req, shape, colorMap); } } } else if (!isMaintainLayer() && !isParent() - && !"ALL".equals(phuc) + && !ALL.equals(phuc) && pfaf.equals(centeredAggr)) { Collection allPfafs = templates .getMap(getSiteKey(), cwa, - "ALL").keySet(); + ALL).keySet(); if (allPfafs != null) { @@ -2729,19 +2679,19 @@ public class FFMPResource extends .getGeometries( templates, getSiteKey(), - cwa, "ALL"); + cwa, ALL); IColormapShadedShape shape = shadedShapes - .getShape(cwa, "ALL", + .getShape(cwa, ALL, req.target, descriptor); - shadedHuc = "ALL"; + shadedHuc = ALL; for (Long allPfaf : allPfafs) { generateShapes(templates, - "ALL", allPfaf, + ALL, allPfaf, allGeomMap, req, shape, colorMap); } @@ -2768,17 +2718,16 @@ public class FFMPResource extends Map allGeomMap = hucGeomFactory .getGeometries(templates, - getSiteKey(), cwa, - "ALL"); + getSiteKey(), cwa, ALL); IColormapShadedShape shape = shadedShapes - .getShape(cwa, "ALL", - req.target, descriptor); + .getShape(cwa, ALL, req.target, + descriptor); - shadedHuc = "ALL"; + shadedHuc = ALL; for (Long allPfaf : pfafsToProcess) { - generateShapes(templates, "ALL", + generateShapes(templates, ALL, allPfaf, allGeomMap, req, shape, colorMap); } @@ -2894,7 +2843,7 @@ public class FFMPResource extends try { color = getColor(pfaf, req.time.getRefTime(), - !"ALL".equals(huc)); + !ALL.equals(huc)); if (color != null) { if (!shape.getColorKeys().contains(pfaf)) { @@ -2969,7 +2918,7 @@ public class FFMPResource extends Map geomMap = hucGeomFactory .getGeometries(templates, getSiteKey(), cwa, - "ALL"); + ALL); for (Long pfaf : streamPfafIds) { // TODO: streamPfafIds should be ordered by @@ -3028,7 +2977,7 @@ public class FFMPResource extends for (DomainXML domains : templates.getDomains()) { String cwa = domains.getCwa(); Map geomMap = hucGeomFactory.getGeometries( - templates, getSiteKey(), cwa, "ALL"); + templates, getSiteKey(), cwa, ALL); if (geomMap != null) { for (Long pfaf : geomMap.keySet()) { @@ -3309,7 +3258,7 @@ public class FFMPResource extends try { rateBasin = monitor.getGraphRateBasin(getProduct(), getSiteKey(), getDataKey(), fvgbmd == null ? getProduct().getRate() - : getProduct().getVirtual(), oldestRefTime, "ALL", + : getProduct().getVirtual(), oldestRefTime, ALL, dataId); ArrayList rateTimes = new ArrayList(); @@ -3333,13 +3282,13 @@ public class FFMPResource extends try { qpeBasin = monitor.getGraphQPEBasin(getProduct(), getSiteKey(), getDataKey(), fvgbmd == null ? getProduct().getQpe() - : getProduct().getVirtual(), oldestRefTime, "ALL", + : getProduct().getVirtual(), oldestRefTime, ALL, dataId); ArrayList qpeTimes = new ArrayList(); if (qpeBasin != null) { - + for (Date date : qpeBasin.getValues().keySet()) { double dtime = FFMPGuiUtils.getTimeDiff(mostRecentRefTime, @@ -3363,7 +3312,7 @@ public class FFMPResource extends try { qpfBasin = monitor.getGraphQPFBasin(getProduct(), getSiteKey(), - getDataKey(), null, oldestRefTime, "ALL", basinPfaf); + getDataKey(), null, oldestRefTime, ALL, basinPfaf); Float qpfFloat = qpfBasin.getValue(monitor.getQpfWindow() .getBeforeTime(), monitor.getQpfWindow().getAfterTime()); @@ -3408,7 +3357,7 @@ public class FFMPResource extends guidBasin = (FFMPGuidanceBasin) monitor.getGraphGuidanceBasin( getProduct(), getSiteKey(), getDataKey(), null, - oldestRefTime, "ALL", basinPfaf); + oldestRefTime, ALL, basinPfaf); ArrayList guidTimes = new ArrayList(); for (SourceXML ffgSource : getProduct().getGuidanceSourcesByType( ffgGraphType)) { @@ -3597,7 +3546,7 @@ public class FFMPResource extends if (tableTime == null) { tableTime = new Date(); } - + synchronized (tableTime) { Date recentTime = getMostRecentTime(); long time = new Double(recentTime.getTime() - (1000 * 3600) @@ -3766,7 +3715,7 @@ public class FFMPResource extends public synchronized ArrayList getTimeOrderedKeys() { if (timeOrderedKeys == null || !toKeysInitialized) { toKeysInitialized = true; - + // stand alone displays use this timeOrderedKeys = new ArrayList(); @@ -4254,7 +4203,7 @@ public class FFMPResource extends ArrayList hucsToLoad = new ArrayList(); if (isWorstCase) { - hucsToLoad.add("ALL"); + hucsToLoad.add(ALL); } // tertiary loader only loads ALL @@ -4263,8 +4212,8 @@ public class FFMPResource extends hucsToLoad.add(getHuc()); } } else { - if (!hucsToLoad.contains("ALL")) { - hucsToLoad.add("ALL"); + if (!hucsToLoad.contains(ALL)) { + hucsToLoad.add(ALL); } } // destroy any old loader diff --git a/cave/com.raytheon.uf.viz.npp.crimss/.classpath b/cave/com.raytheon.uf.viz.npp.crimss/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.crimss/.project b/cave/com.raytheon.uf.viz.npp.crimss/.project new file mode 100644 index 0000000000..cc02971344 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.npp.crimss + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.npp.crimss/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.npp.crimss/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..1ceaf3e7da --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Dec 05 10:22:58 CST 2011 +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/cave/com.raytheon.uf.viz.npp.crimss/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.npp.crimss/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..c0299fc9b0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/META-INF/MANIFEST.MF @@ -0,0 +1,55 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Crimss +Bundle-SymbolicName: com.raytheon.uf.viz.npp.crimss;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.npp.crimss.Activator +Bundle-Vendor: RAYTHEON +Eclipse-BuddyPolicy: registered, ext, global +Eclipse-RegisterBuddy: com.raytheon.uf.common.serialization +Require-Bundle: org.eclipse.core.runtime, + org.eclipse.ui;bundle-version="3.6.1", + com.raytheon.uf.viz.points;bundle-version="1.0.0", + gov.noaa.nws.ncep.ui.nsharp;bundle-version="1.0.0" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Import-Package: com.raytheon.uf.common.dataplugin, + com.raytheon.uf.common.dataplugin.npp.crimss, + com.raytheon.uf.common.dataquery.requests, + com.raytheon.uf.common.dataquery.responses, + com.raytheon.uf.common.geospatial, + com.raytheon.uf.common.pointdata, + com.raytheon.uf.common.serialization, + com.raytheon.uf.common.serialization.comm, + com.raytheon.uf.common.status, + com.raytheon.uf.common.time, + com.raytheon.uf.viz.core, + com.raytheon.uf.viz.core.drawables, + com.raytheon.uf.viz.core.exception, + com.raytheon.uf.viz.core.map, + com.raytheon.uf.viz.core.maps.display, + com.raytheon.uf.viz.core.procedures, + com.raytheon.uf.viz.core.requests, + com.raytheon.uf.viz.core.rsc, + com.raytheon.uf.viz.core.rsc.capabilities, + com.raytheon.uf.viz.d2d.core, + com.raytheon.uf.viz.d2d.core.map, + com.raytheon.uf.viz.d2d.nsharp.display, + com.raytheon.uf.viz.d2d.nsharp.rsc, + com.raytheon.uf.viz.productbrowser, + com.raytheon.viz.core.graphing, + com.raytheon.viz.pointdata, + com.raytheon.viz.ui, + com.raytheon.viz.ui.editor, + com.raytheon.viz.ui.input, + com.vividsolutions.jts.geom, + gov.noaa.nws.ncep.edex.common.sounding, + gov.noaa.nws.ncep.ui.nsharp, + gov.noaa.nws.ncep.ui.nsharp.natives, + gov.noaa.nws.ncep.ui.nsharp.skewt, + javax.measure.converter, + javax.measure.unit, + org.eclipse.swt.graphics, + org.eclipse.swt.widgets +Export-Package: com.raytheon.uf.viz.npp.crimss, + com.raytheon.uf.viz.npp.crimss.map diff --git a/cave/com.raytheon.uf.viz.npp.crimss/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/cave/com.raytheon.uf.viz.npp.crimss/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject new file mode 100644 index 0000000000..5a3ce6aeeb --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -0,0 +1,2 @@ +com.raytheon.uf.viz.npp.crimss.CrimssNSharpResourceData +com.raytheon.uf.viz.npp.crimss.map.CrimssMapResourceData \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.crimss/build.properties b/cave/com.raytheon.uf.viz.npp.crimss/build.properties new file mode 100644 index 0000000000..6e2f847b66 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + localization/ diff --git a/cave/com.raytheon.uf.viz.npp.crimss/localization/bundles/crimssAvailability.xml b/cave/com.raytheon.uf.viz.npp.crimss/localization/bundles/crimssAvailability.xml new file mode 100644 index 0000000000..c45a461ad3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/localization/bundles/crimssAvailability.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.crimss/localization/menus/npp/crimss/crimssMenuItems.xml b/cave/com.raytheon.uf.viz.npp.crimss/localization/menus/npp/crimss/crimssMenuItems.xml new file mode 100644 index 0000000000..2479336090 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/localization/menus/npp/crimss/crimssMenuItems.xml @@ -0,0 +1,28 @@ + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.crimss/plugin.xml b/cave/com.raytheon.uf.viz.npp.crimss/plugin.xml new file mode 100644 index 0000000000..18716f966b --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/plugin.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/Activator.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/Activator.java new file mode 100644 index 0000000000..e9a4478804 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/Activator.java @@ -0,0 +1,30 @@ +package com.raytheon.uf.viz.npp.crimss; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/CrimssDataDefinition.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/CrimssDataDefinition.java new file mode 100644 index 0000000000..a83c27c8f4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/CrimssDataDefinition.java @@ -0,0 +1,242 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.crimss; + +import gov.noaa.nws.ncep.ui.nsharp.skewt.NsharpSkewTEditor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.raytheon.uf.common.dataplugin.npp.crimss.CrimssRecord; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.requests.ThriftClient; +import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.ResourceType; +import com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpDescriptor; +import com.raytheon.uf.viz.d2d.nsharp.display.D2DNSharpDisplay; +import com.raytheon.uf.viz.npp.crimss.map.CrimssMapResourceData; +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.productbrowser.AbstractRequestableProductBrowserDataDefinition; +import com.raytheon.uf.viz.productbrowser.ProductBrowserLabel; +import com.raytheon.viz.ui.UiUtil; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 6, 2011            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class CrimssDataDefinition + extends + AbstractRequestableProductBrowserDataDefinition { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CrimssDataDefinition.class); + + private static final String MAP_RESOURCE = "map_resource"; + + private static final String POINT = "point"; + + private static final double DISTANCE = 0.8; + + public CrimssDataDefinition() { + productName = "crimss"; + displayName = "CrIMSS"; + order = new String[] { "pluginName", POINT }; + order = getOrder(); + loadProperties = new LoadProperties(); + loadProperties.setResourceType(getResourceType()); + } + + @Override + protected String[] queryData(String param, + HashMap queryList) { + if (param.equals(POINT)) { + // TODO depending on how much data we have this might be way too + // data to request. + List points = new ArrayList(); + PointsDataManager pdm = PointsDataManager.getInstance(); + DbQueryRequest request = new DbQueryRequest(); + request.setEntityClass(CrimssRecord.class.getName()); + request.setDistinct(true); + request.addRequestField(CrimssRecord.LATITUDE); + request.addRequestField(CrimssRecord.LONGITUDE); + try { + DbQueryResponse response = (DbQueryResponse) ThriftClient + .sendRequest(request); + for (Map result : response.getResults()) { + float lat = ((Number) result.get(CrimssRecord.LATITUDE)) + .floatValue(); + float lon = ((Number) result.get(CrimssRecord.LONGITUDE)) + .floatValue(); + Coordinate c = new Coordinate(lon, lat); + for (String point : pdm.getPointNames()) { + if (points.contains(point)) { + continue; + } + Coordinate p = pdm.getCoordinate(point); + if (p.distance(c) < DISTANCE) { + points.add(point); + } + } + } + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + points.add(MAP_RESOURCE); + return points.toArray(new String[0]); + } + return super.queryData(param, queryList); + } + + @Override + public List formatData(String param, + String[] parameters) { + if (param.equals(POINT)) { + Arrays.sort(parameters); + List temp = new ArrayList(); + for (int i = 0; i < parameters.length; i++) { + if (parameters[i].equals(MAP_RESOURCE)) { + temp.add(0, new ProductBrowserLabel("CrIMSS Availability", + parameters[i])); + } else { + temp.add(new ProductBrowserLabel("Point " + parameters[i], + parameters[i])); + } + } + return temp; + } + return super.formatData(param, parameters); + } + + @Override + public HashMap getProductParameters( + String[] selection, String[] order) { + HashMap queryList = new HashMap(); + queryList.put(order[0], new RequestConstraint(productName)); + for (int i = 1; i < selection.length; i++) { + if (order[i].equals(POINT)) { + if (!selection[i].equals("map_resource")) { + Coordinate coord = PointsDataManager.getInstance() + .getCoordinate(selection[i]); + RequestConstraint rc = new RequestConstraint(null, + ConstraintType.BETWEEN); + rc.setBetweenValueList(new String[] { + String.valueOf(coord.x - DISTANCE), + String.valueOf(coord.x + DISTANCE) }); + queryList.put(CrimssRecord.LONGITUDE, rc); + rc = new RequestConstraint(null, ConstraintType.BETWEEN); + rc.setBetweenValueList(new String[] { + String.valueOf(coord.y - DISTANCE), + String.valueOf(coord.y + DISTANCE) }); + queryList.put(CrimssRecord.LATITUDE, rc); + if (resourceData != null) { + ((CrimssNSharpResourceData) resourceData) + .setCoordinate(coord); + ((CrimssNSharpResourceData) resourceData) + .setPointName("CrIMSS-Pnt" + selection[i]); + } + } + } else { + queryList.put(order[i], new RequestConstraint(selection[i])); + } + } + + return queryList; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.productbrowser. + * AbstractRequestableProductBrowserDataDefinition#getDescriptorClass() + */ + @Override + protected Class getDescriptorClass() { + if (resourceData instanceof CrimssNSharpResourceData) { + return D2DNSharpDescriptor.class; + } else { + return super.getDescriptorClass(); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.productbrowser. + * AbstractRequestableProductBrowserDataDefinition + * #openNewEditor(java.lang.String) + */ + @Override + protected IDisplayPaneContainer openNewEditor(String editorId) { + if (NsharpSkewTEditor.EDITOR_ID.equals(editorId)) { + return UiUtil.createEditor(editorId, new D2DNSharpDisplay()); + } else { + return super.openNewEditor(editorId); + } + } + + @Override + public AbstractRequestableResourceData getResourceData() { + return resourceData; + } + + @Override + public void constructResource(String[] selection, ResourceType type) { + resourceData = null; + for (int i = 0; i < selection.length; i++) { + if (order[i].equals(POINT)) { + if (selection[i].equals(MAP_RESOURCE)) { + resourceData = new CrimssMapResourceData(); + } + } + } + if (resourceData == null) { + resourceData = new CrimssNSharpResourceData(); + } + super.constructResource(selection, type); + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/CrimssNSharpResourceData.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/CrimssNSharpResourceData.java new file mode 100644 index 0000000000..8993b83f32 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/CrimssNSharpResourceData.java @@ -0,0 +1,401 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.crimss; + +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingCube; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingCube.QueryStatus; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingLayer; +import gov.noaa.nws.ncep.edex.common.sounding.NcSoundingProfile; +import gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo; +import gov.noaa.nws.ncep.ui.nsharp.natives.NsharpDataHandling; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import javax.measure.converter.UnitConverter; +import javax.measure.unit.SI; +import javax.measure.unit.Unit; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import com.raytheon.uf.common.dataplugin.npp.crimss.CrimssRecord; +import com.raytheon.uf.common.pointdata.PointDataContainer; +import com.raytheon.uf.common.pointdata.PointDataView; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.d2d.nsharp.rsc.D2DNSharpResourceData; +import com.raytheon.viz.pointdata.PointDataRequest; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 5, 2011            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +public class CrimssNSharpResourceData extends D2DNSharpResourceData { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(CrimssNSharpResourceData.class); + + private static final String PLUGIN = "crimss"; + + private static final String[] PARAMETERS = { CrimssRecord.LONGITUDE, + CrimssRecord.LATITUDE, CrimssRecord.PDV_SURFACE_PRESSURE, + CrimssRecord.PDV_ALTITUDE, CrimssRecord.PDV_P_ALTITUDE, + CrimssRecord.PDV_H2O, CrimssRecord.PDV_P_H2O, + CrimssRecord.PDV_TEMPERATURE, CrimssRecord.PDV_P_TEMPERATURE }; + + private static final Unit PRESSURE_UNIT = SI.HECTO(SI.PASCAL); + + private static final Unit HEIGHT_UNIT = SI.METER; + + private static final Unit TEMPERATURE_UNIT = SI.CELSIUS; + + private static final Unit H2O_UNIT = SI.GRAM.divide(SI.KILOGRAM); + + private static final Unit DEWPOINT_UNIT = SI.CELSIUS; + + public CrimssNSharpResourceData() { + super("CRiMSS"); + } + + @Override + protected void preparePointInfo() throws VizException { + // everything should already be set + return; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.d2d.nsharp.rsc.D2DNSharpResourceData#getSoundingCube + * (gov.noaa.nws.ncep.ui.nsharp.NsharpStationInfo) + */ + @Override + protected NcSoundingCube getSoundingCube(NsharpStationInfo stnInfo) { + DataTime time = new DataTime(stnInfo.getReftime()); + try { + PointDataContainer pdc = PointDataRequest + .requestPointDataAllLevels(time, PLUGIN, PARAMETERS, null, + getMetadataMap()); + PointDataView pdv = null; + Coordinate closest = null; + for (int i = 0; i < pdc.getCurrentSz(); i++) { + PointDataView testPdv = pdc.readRandom(i); + Coordinate p = new Coordinate( + testPdv.getFloat(CrimssRecord.LONGITUDE), + testPdv.getFloat(CrimssRecord.LATITUDE)); + if (closest == null + || coordinate.distance(p) < coordinate + .distance(closest)) { + pdv = testPdv; + closest = p; + } + } + if (pdv == null) { + return null; + } + List layers = new ArrayList(); + layers.add(getSurfacePressureLayer(pdv)); + layers.addAll(getHeightLayers(pdv)); + layers.addAll(getTemperatureLayers(pdv)); + layers.addAll(getDewpointLayers(pdv)); + Collections.sort(layers, + NsharpDataHandling.reversePressureHeightWindComparator()); + mergeDuplicates(layers); + // We have to interpolate everything so that height,temperature, and + // dewpoint are available on all levels. + interpolateHeight(layers); + interpolateTemperature(layers); + interpolateDewpoint(layers); + Iterator iter = layers.iterator(); + while (iter.hasNext()) { + NcSoundingLayer layer = iter.next(); + if (layer.getPressure() < 0) { + iter.remove(); + } else if (layer.getGeoHeight() < 0) { + iter.remove(); + + } else if (layer.getTemperature() < -300) { + iter.remove(); + + } else if (layer.getDewpoint() < -300) { + iter.remove(); + } + } + NcSoundingProfile profile = new NcSoundingProfile(); + profile.setSoundingLyLst(layers); + // TODO populate other fields in profile + NcSoundingCube cube = new NcSoundingCube(Arrays.asList(profile)); + cube.setRtnStatus(QueryStatus.OK); + return cube; + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e); + } + return null; + } + + private static NcSoundingLayer getSurfacePressureLayer(PointDataView pdv) { + float surfacePressure = pdv.getFloat(CrimssRecord.PDV_SURFACE_PRESSURE); + Unit surfacePressureUnit = pdv + .getUnit(CrimssRecord.PDV_SURFACE_PRESSURE); + if (PRESSURE_UNIT.isCompatible(surfacePressureUnit)) { + UnitConverter converter = surfacePressureUnit + .getConverterTo(PRESSURE_UNIT); + surfacePressure = (float) converter.convert(surfacePressure); + } + return new NcSoundingLayer(surfacePressure, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING); + } + + private static List getHeightLayers(PointDataView pdv) { + List layers = new ArrayList(); + UnitConverter heightConverter = UnitConverter.IDENTITY; + Unit heightUnit = pdv.getUnit(CrimssRecord.PDV_ALTITUDE); + if (HEIGHT_UNIT.isCompatible(heightUnit)) { + heightConverter = heightUnit.getConverterTo(HEIGHT_UNIT); + } + UnitConverter pressureConverter = UnitConverter.IDENTITY; + Unit pressureUnit = pdv.getUnit(CrimssRecord.PDV_P_ALTITUDE); + if (PRESSURE_UNIT.isCompatible(pressureUnit)) { + pressureConverter = pressureUnit.getConverterTo(PRESSURE_UNIT); + } + Number[] altitudeArray = pdv + .getNumberAllLevels(CrimssRecord.PDV_ALTITUDE); + Number[] pressureArray = pdv + .getNumberAllLevels(CrimssRecord.PDV_P_ALTITUDE); + for (int j = 0; j < altitudeArray.length; j++) { + float altitude = altitudeArray[j].floatValue(); + altitude = (float) heightConverter.convert(altitude); + float pressure = pressureArray[j].floatValue(); + pressure = (float) pressureConverter.convert(pressure); + NcSoundingLayer layer = new NcSoundingLayer(pressure, altitude, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING); + layers.add(layer); + } + return layers; + } + + private static List getTemperatureLayers(PointDataView pdv) { + List layers = new ArrayList(); + UnitConverter temperatureConverter = UnitConverter.IDENTITY; + Unit temperatureUnit = pdv.getUnit(CrimssRecord.PDV_TEMPERATURE); + if (TEMPERATURE_UNIT.isCompatible(temperatureUnit)) { + temperatureConverter = temperatureUnit + .getConverterTo(TEMPERATURE_UNIT); + } + UnitConverter pressureConverter = UnitConverter.IDENTITY; + Unit pressureUnit = pdv.getUnit(CrimssRecord.PDV_P_TEMPERATURE); + if (PRESSURE_UNIT.isCompatible(pressureUnit)) { + pressureConverter = pressureUnit.getConverterTo(PRESSURE_UNIT); + } + Number[] temperatureArray = pdv + .getNumberAllLevels(CrimssRecord.PDV_TEMPERATURE); + Number[] pressureArray = pdv + .getNumberAllLevels(CrimssRecord.PDV_P_TEMPERATURE); + + for (int j = 0; j < temperatureArray.length; j++) { + float temperature = temperatureArray[j].floatValue(); + temperature = (float) temperatureConverter.convert(temperature); + float pressure = pressureArray[j].floatValue(); + pressure = (float) pressureConverter.convert(pressure); + NcSoundingLayer layer = new NcSoundingLayer(pressure, + NcSoundingLayer.MISSING, temperature, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING); + layers.add(layer); + } + return layers; + } + + private static List getDewpointLayers(PointDataView pdv) { + List layers = new ArrayList(); + UnitConverter h2oConverter = UnitConverter.IDENTITY; + Unit h2oUnit = pdv.getUnit(CrimssRecord.PDV_H2O); + if (H2O_UNIT.isCompatible(h2oUnit)) { + h2oConverter = h2oUnit.getConverterTo(H2O_UNIT); + } + UnitConverter dewpointConverter = UnitConverter.IDENTITY; + Unit dewpointUnit = SI.KELVIN; + if (DEWPOINT_UNIT.isCompatible(dewpointUnit)) { + dewpointConverter = dewpointUnit.getConverterTo(DEWPOINT_UNIT); + } + UnitConverter pressureConverter = UnitConverter.IDENTITY; + Unit pressureUnit = pdv.getUnit(CrimssRecord.PDV_P_H2O); + if (PRESSURE_UNIT.isCompatible(pressureUnit)) { + pressureConverter = pressureUnit.getConverterTo(PRESSURE_UNIT); + } + Number[] h2oArray = pdv.getNumberAllLevels(CrimssRecord.PDV_H2O); + Number[] pressureArray = pdv.getNumberAllLevels(CrimssRecord.PDV_P_H2O); + + for (int j = 0; j < h2oArray.length; j++) { + float pressure = pressureArray[j].floatValue(); + pressure = (float) pressureConverter.convert(pressure); + float h2o = h2oArray[j].floatValue(); + h2o = (float) h2oConverter.convert(h2o); + float dpt = convertH2OtoDewpoint(h2o, pressure); + dpt = (float) dewpointConverter.convert(dpt); + NcSoundingLayer layer = new NcSoundingLayer(pressure, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + (float) dpt, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, + NcSoundingLayer.MISSING, NcSoundingLayer.MISSING, h2o, + NcSoundingLayer.MISSING); + layers.add(layer); + } + return layers; + } + + // convert h2o in g/kg and pressure in hPa to dewpoint in kelvin. + private static float convertH2OtoDewpoint(float h2o, float pressure) { + double eee = pressure * h2o / (622.0 + 0.378 * h2o); + double b = 26.66082 - Math.log(eee); + return (float) ((b - Math.sqrt(b * b - 223.1986)) / 0.0182758048); + } + + private static void mergeDuplicates(List layers) { + // Merge any soundings at same pressure. + Iterator iter = layers.iterator(); + NcSoundingLayer prev = iter.next(); + while (iter.hasNext()) { + NcSoundingLayer next = iter.next(); + if (prev.getPressure() == next.getPressure()) { + if (next.getGeoHeight() > 0) { + prev.setGeoHeight(next.getGeoHeight()); + } + if (next.getDewpoint() > -300) { + prev.setDewpoint(next.getDewpoint()); + } + if (next.getTemperature() > -300) { + prev.setTemperature(next.getTemperature()); + } + iter.remove(); + } else { + prev = next; + } + } + } + + private static void interpolateHeight(List layers) { + int belowIndex = -1; + for (int i = 0; i < layers.size(); i++) { + NcSoundingLayer layerAbove = layers.get(i); + if (layerAbove.getGeoHeight() < 0) { + continue; + } + if (belowIndex == -1) { + belowIndex = i; + continue; + } + NcSoundingLayer layerBelow = layers.get(belowIndex); + double diff = layerAbove.getGeoHeight() - layerBelow.getGeoHeight(); + double pchg1 = Math.log(layerBelow.getPressure() + / layerAbove.getPressure()); + for (int j = belowIndex + 1; j < i; j += 1) { + NcSoundingLayer layer = layers.get(j); + double pchg2 = Math.log(layerBelow.getPressure() + / layer.getPressure()); + layer.setGeoHeight((float) (layerBelow.getGeoHeight() + ((pchg2 / pchg1) * diff))); + } + belowIndex = i; + } + } + + private static void interpolateTemperature(List layers) { + int belowIndex = -1; + for (int i = 0; i < layers.size(); i++) { + NcSoundingLayer layerAbove = layers.get(i); + if (layerAbove.getTemperature() < -300) { + continue; + } + if (belowIndex == -1) { + belowIndex = i; + continue; + } + NcSoundingLayer layerBelow = layers.get(belowIndex); + double diff = layerAbove.getTemperature() + - layerBelow.getTemperature(); + double pchg1 = Math.log(layerBelow.getPressure() + / layerAbove.getPressure()); + for (int j = belowIndex + 1; j < i; j += 1) { + NcSoundingLayer layer = layers.get(j); + double pchg2 = Math.log(layerBelow.getPressure() + / layer.getPressure()); + layer.setTemperature((float) (layerBelow.getTemperature() + ((pchg2 / pchg1) * diff))); + } + belowIndex = i; + } + } + + private static void interpolateDewpoint(List layers) { + int belowIndex = -1; + for (int i = 0; i < layers.size(); i++) { + NcSoundingLayer layerAbove = layers.get(i); + if (layerAbove.getDewpoint() < -300) { + continue; + } + if (belowIndex == -1) { + belowIndex = i; + continue; + } + NcSoundingLayer layerBelow = layers.get(belowIndex); + double diff = layerAbove.getDewpoint() - layerBelow.getDewpoint(); + double pchg1 = Math.log(layerBelow.getPressure() + / layerAbove.getPressure()); + for (int j = belowIndex + 1; j < i; j += 1) { + NcSoundingLayer layer = layers.get(j); + double pchg2 = Math.log(layerBelow.getPressure() + / layer.getPressure()); + layer.setDewpoint((float) (layerBelow.getDewpoint() + ((pchg2 / pchg1) * diff))); + } + belowIndex = i; + } + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapInputManager.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapInputManager.java new file mode 100644 index 0000000000..a568b1b75c --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapInputManager.java @@ -0,0 +1,176 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.crimss.map; + +import java.util.Collection; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.IWorkbenchPart; + +import com.raytheon.uf.common.dataplugin.npp.crimss.CrimssRecord; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.viz.ui.VizWorkbenchManager; +import com.raytheon.viz.ui.input.InputAdapter; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Input manager for the CrimssMapResource + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 9, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class CrimssMapInputManager extends InputAdapter { + + private Cursor handCursor; + + private Cursor arrowCursor; + + private CrimssMapResource resource; + + private CrimssRecord closestRecord; + + private int downX, downY; + + public CrimssMapInputManager(CrimssMapResource resource) { + this.resource = resource; + Display display = Display.getCurrent(); + handCursor = new Cursor(display, SWT.CURSOR_HAND); + arrowCursor = new Cursor(display, SWT.CURSOR_ARROW); + } + + public void dispose() { + handCursor.dispose(); + arrowCursor.dispose(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.InputAdapter#handleMouseMove(int, int) + */ + @Override + public boolean handleMouseMove(int x, int y) { + boolean wasClosest = closestRecord != null; + closestRecord = null; + + if (resource.isEditable()) { + Collection records = resource.getCurrentRecords(); + if (records != null) { + double radius = resource.getRadius(); + Coordinate c = new Coordinate(x, y); + double bestDist = Double.MAX_VALUE; + for (CrimssRecord record : records) { + double lat = record.getLatitude(); + double lon = record.getLongitude(); + double[] pixel = resource.getResourceContainer() + .translateInverseClick(new Coordinate(lon, lat)); + Coordinate p = new Coordinate(pixel[0], pixel[1]); + double dist = p.distance(c); + if (dist < bestDist && dist < radius) { + closestRecord = record; + bestDist = dist; + } + } + } + } + + if (wasClosest && closestRecord == null) { + getShell().setCursor(arrowCursor); + } else if (!wasClosest && closestRecord != null) { + getShell().setCursor(handCursor); + } + + return super.handleMouseMove(x, y); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.InputAdapter#handleMouseDown(int, int, + * int) + */ + @Override + public boolean handleMouseDown(int x, int y, int mouseButton) { + if (mouseButton == 1) { + downX = x; + downY = y; + } + return super.handleMouseDown(x, y, mouseButton); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.input.InputAdapter#handleMouseUp(int, int, int) + */ + @Override + public boolean handleMouseUp(int x, int y, int mouseButton) { + int downX = this.downX; + int downY = this.downY; + this.downX = this.downY = -1; + if (closestRecord != null && mouseButton == 1 && downX == x + && downY == y) { + resource.loadSoundingResource(closestRecord); + closestRecord = null; + return true; + } + return super.handleMouseUp(x, y, mouseButton); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.input.InputAdapter#handleMouseExit(org.eclipse.swt + * .widgets.Event) + */ + @Override + public boolean handleMouseExit(Event event) { + closestRecord = null; + getShell().setCursor(arrowCursor); + return super.handleMouseExit(event); + } + + private Shell getShell() { + IDisplayPaneContainer container = resource.getResourceContainer(); + if (container instanceof IWorkbenchPart) { + return ((IWorkbenchPart) container).getSite().getShell(); + } else { + return VizWorkbenchManager.getInstance().getCurrentWindow() + .getShell(); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java new file mode 100644 index 0000000000..cdf715f959 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResource.java @@ -0,0 +1,230 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.crimss.map; + +import gov.noaa.nws.ncep.ui.nsharp.display.NsharpSkewTPaneDisplay; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.npp.crimss.CrimssRecord; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.time.BinOffset; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.DescriptorMap; +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.AbstractRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.map.IMapDescriptor; +import com.raytheon.uf.viz.core.procedures.Bundle; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.EditableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; +import com.raytheon.uf.viz.npp.crimss.CrimssNSharpResourceData; +import com.raytheon.viz.ui.MenuLoader; +import com.raytheon.viz.ui.UiUtil; +import com.raytheon.viz.ui.editor.AbstractEditor; +import com.raytheon.viz.ui.input.EditableManager; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 7, 2011            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +public class CrimssMapResource extends + AbstractVizResource { + + private CrimssMapInputManager inputManager; + + private Map> records = new HashMap>(); + + protected CrimssMapResource(CrimssMapResourceData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + this.inputManager = new CrimssMapInputManager(this); + this.dataTimes = new ArrayList(); + getCapability(EditableCapability.class).setEditable(true); + resourceData.addChangeListener(new IResourceDataChanged() { + + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.DATA_UPDATE) { + if (object instanceof PluginDataObject[]) { + for (PluginDataObject pdo : (PluginDataObject[]) object) { + addRecord((CrimssRecord) pdo); + } + } + } + } + }); + } + + Collection getCurrentRecords() { + return records.get(descriptor.getTimeForResource(this)); + } + + public void addRecord(CrimssRecord record) { + DataTime time = record.getDataTime(); + BinOffset binOffset = resourceData.getBinOffset(); + if (binOffset != null) { + time = binOffset.getNormalizedTime(time); + } + Set pdos = this.records.get(time); + if (pdos == null) { + pdos = new HashSet(); + this.records.put(time, pdos); + } + if (!this.dataTimes.contains(time)) { + this.dataTimes.add(time); + } + pdos.add(record); + } + + @Override + public void remove(DataTime dataTime) { + records.remove(dataTime); + super.remove(dataTime); + } + + @Override + protected void disposeInternal() { + inputManager.dispose(); + getResourceContainer().unregisterMouseHandler(inputManager); + } + + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + DataTime time = paintProps.getDataTime(); + if (time == null) { + return; + } + Set records = this.records.get(time); + if (records == null) { + return; + } + RGB color = getCapability(ColorableCapability.class).getColor(); + List circles = new ArrayList( + records.size()); + for (CrimssRecord record : records) { + double lat = record.getLatitude(); + double lon = record.getLongitude(); + double[] pixel = descriptor.worldToPixel(new double[] { lon, lat }); + DrawableCircle circle = new DrawableCircle(); + circle.setCoordinates(pixel[0], pixel[1]); + circle.screenRadius = getRadius() - 1; + circle.basics.color = color; + circle.filled = true; + circles.add(circle); + } + target.drawCircle(circles.toArray(new DrawableCircle[0])); + + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + EditableManager.makeEditable(this, + getCapability(EditableCapability.class).isEditable()); + getResourceContainer().registerMouseHandler(inputManager); + } + + /** + * Check if the resource is editable + * + */ + public boolean isEditable() { + return getCapability(EditableCapability.class).isEditable(); + } + + double getRadius() { + return 8 * getCapability(MagnificationCapability.class) + .getMagnification(); + } + + void loadSoundingResource(CrimssRecord record) { + HashMap metadataMap = new HashMap( + resourceData.getMetadataMap()); + RequestConstraint rc = new RequestConstraint(null, + ConstraintType.BETWEEN); + rc.setBetweenValueList(new String[] { + String.valueOf(record.getLongitude() - 0.01), + String.valueOf(record.getLongitude() + 0.01) }); + metadataMap.put(CrimssRecord.LONGITUDE, rc); + rc = new RequestConstraint(null, ConstraintType.BETWEEN); + rc.setBetweenValueList(new String[] { + String.valueOf(record.getLatitude() - 0.01), + String.valueOf(record.getLatitude() + 0.01) }); + metadataMap.put(CrimssRecord.LATITUDE, rc); + CrimssNSharpResourceData resourceData = new CrimssNSharpResourceData(); + resourceData.setCoordinate(new Coordinate(record.getLongitude(), record + .getLatitude())); + resourceData.setPointName(String.format("CrIMSS-%.2f,%.2f", + record.getLongitude(), record.getLatitude())); + resourceData.setMetadataMap(metadataMap); + ResourcePair pair = new ResourcePair(); + pair.setResourceData(resourceData); + pair.setLoadProperties(new LoadProperties()); + NsharpSkewTPaneDisplay display = new NsharpSkewTPaneDisplay(); + display.getDescriptor().getResourceList().add(pair); + String editorId = DescriptorMap.getEditorId(display.getDescriptor() + .getClass().getName()); + AbstractEditor editor = UiUtil.createOrOpenEditor(editorId, + display.cloneDisplay()); + Bundle b = new Bundle(); + b.setDisplays(new AbstractRenderableDisplay[] { display }); + Job j = new MenuLoader(b, editor); + j.schedule(); + } + + @Override + public String getName() { + return "CrIMSS Availability"; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResourceData.java b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResourceData.java new file mode 100644 index 0000000000..450f48facb --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.crimss/src/com/raytheon/uf/viz/npp/crimss/map/CrimssMapResourceData.java @@ -0,0 +1,65 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.crimss.map; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.npp.crimss.CrimssRecord; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 7, 2011            bsteffen     Initial creation
+ * 
+ * 
+ * + * @author bsteffen + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +public class CrimssMapResourceData extends AbstractRequestableResourceData { + + @Override + protected AbstractVizResource constructResource( + LoadProperties loadProperties, PluginDataObject[] objects) + throws VizException { + CrimssMapResource resource = new CrimssMapResource(this, loadProperties); + for (PluginDataObject pdo : objects) { + if (pdo instanceof CrimssRecord) { + resource.addRecord((CrimssRecord) pdo); + } + } + return resource; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.feature/.project b/cave/com.raytheon.uf.viz.npp.feature/.project new file mode 100644 index 0000000000..1d3ac2a01e --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.feature/.project @@ -0,0 +1,17 @@ + + + com.raytheon.uf.viz.npp.feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/cave/com.raytheon.uf.viz.npp.feature/build.properties b/cave/com.raytheon.uf.viz.npp.feature/build.properties new file mode 100644 index 0000000000..64f93a9f0b --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/cave/com.raytheon.uf.viz.npp.feature/com.raytheon.uf.viz.npp.feature.ecl b/cave/com.raytheon.uf.viz.npp.feature/com.raytheon.uf.viz.npp.feature.ecl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cave/com.raytheon.uf.viz.npp.feature/feature.xml b/cave/com.raytheon.uf.viz.npp.feature/feature.xml new file mode 100644 index 0000000000..ce92ce2d62 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.feature/feature.xml @@ -0,0 +1,53 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/.classpath b/cave/com.raytheon.uf.viz.npp.viirs/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/.project b/cave/com.raytheon.uf.viz.npp.viirs/.project new file mode 100644 index 0000000000..3f9ee6ec27 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/.project @@ -0,0 +1,40 @@ + + + com.raytheon.uf.viz.npp.viirs + + + + + + org.python.pydev.PyDevBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.api.tools.apiAnalysisBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.pde.api.tools.apiAnalysisNature + org.python.pydev.pythonNature + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/.pydevproject b/cave/com.raytheon.uf.viz.npp.viirs/.pydevproject new file mode 100644 index 0000000000..a9cca037b3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/.pydevproject @@ -0,0 +1,7 @@ + + + + +Default +python 2.7 + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.npp.viirs/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..3a2d12e2e7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Wed Nov 30 13:51:22 CST 2011 +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/cave/com.raytheon.uf.viz.npp.viirs/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.npp.viirs/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..d3d2f1d41d --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/META-INF/MANIFEST.MF @@ -0,0 +1,30 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: VIIRS Satellite +Bundle-SymbolicName: com.raytheon.uf.viz.npp.viirs;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.npp.viirs.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.common.time;bundle-version="1.12.1174", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174", + com.raytheon.uf.common.colormap;bundle-version="1.12.1174", + org.geotools;bundle-version="2.6.4", + com.raytheon.uf.common.datastorage;bundle-version="1.12.1174", + com.raytheon.uf.common.datastorage.hdf5;bundle-version="1.12.1174", + com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174", + com.raytheon.uf.common.dataplugin.npp.viirs;bundle-version="1.0.0", + javax.measure;bundle-version="1.0.0", + com.raytheon.uf.viz.productbrowser;bundle-version="1.12.1174", + com.raytheon.uf.common.pointdata;bundle-version="1.12.1174", + com.raytheon.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.viz.derivparam;bundle-version="1.12.1174", + com.raytheon.uf.common.derivparam;bundle-version="1.12.1174", + com.raytheon.uf.common.dataplugin.level;bundle-version="1.12.1174", + com.raytheon.uf.common.comm;bundle-version="1.12.1174", + com.raytheon.viz.alerts;bundle-version="1.12.1174" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy diff --git a/cave/com.raytheon.uf.viz.npp.viirs/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject b/cave/com.raytheon.uf.viz.npp.viirs/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject new file mode 100644 index 0000000000..d53a3cf42a --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/META-INF/services/com.raytheon.uf.common.serialization.ISerializableObject @@ -0,0 +1,2 @@ +com.raytheon.uf.viz.npp.viirs.rsc.VIIRSResourceData +com.raytheon.uf.viz.npp.viirs.style.VIIRSDataMatchCriteria diff --git a/cave/com.raytheon.uf.viz.npp.viirs/META-INF/services/com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter b/cave/com.raytheon.uf.viz.npp.viirs/META-INF/services/com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter new file mode 100644 index 0000000000..9bf3ccea45 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/META-INF/services/com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter @@ -0,0 +1 @@ +com.raytheon.uf.viz.npp.viirs.data.VIIRSDataCubeAdapter \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/build.properties b/cave/com.raytheon.uf.viz.npp.viirs/build.properties new file mode 100644 index 0000000000..6e2f847b66 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/build.properties @@ -0,0 +1,6 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml,\ + localization/ diff --git a/cave/com.raytheon.uf.viz.npp.viirs/com.raytheon.uf.viz.npp.viirs.ecl b/cave/com.raytheon.uf.viz.npp.viirs/com.raytheon.uf.viz.npp.viirs.ecl new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/bundles/npp/viirs/singlePanelComposite.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/bundles/npp/viirs/singlePanelComposite.xml new file mode 100644 index 0000000000..08fc8c4d5b --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/bundles/npp/viirs/singlePanelComposite.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + ${productName} + + RED + + ${groupTimeRange;30} + + + + + + + + + + + + + + + GREEN + + ${groupTimeRange;30} + + + + + + + + + + + + + + + BLUE + + ${groupTimeRange;30} + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/bundles/npp/viirs/viirsImagery.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/bundles/npp/viirs/viirsImagery.xml new file mode 100644 index 0000000000..21617e46ad --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/bundles/npp/viirs/viirsImagery.xml @@ -0,0 +1,45 @@ + + + + + + + + + + ${groupTimeRange;30} + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/CA (Low Light Vis).cmap b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/CA (Low Light Vis).cmap new file mode 100644 index 0000000000..b03aa84a69 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/CA (Low Light Vis).cmap @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/IR BrightTemps.cmap b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/IR BrightTemps.cmap new file mode 100644 index 0000000000..5bf07dbff9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/IR BrightTemps.cmap @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/IR Default.cmap b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/IR Default.cmap new file mode 100644 index 0000000000..c2576d7b71 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/IR Default.cmap @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/ZA (Vis Default).cmap b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/ZA (Vis Default).cmap new file mode 100644 index 0000000000..c76ede3f06 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/colormaps/NPP/VIIRS/ZA (Vis Default).cmap @@ -0,0 +1,259 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/derivedParameters/functions/viirs/Math.py b/cave/com.raytheon.uf.viz.npp.viirs/localization/derivedParameters/functions/viirs/Math.py new file mode 100644 index 0000000000..cf80caf809 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/derivedParameters/functions/viirs/Math.py @@ -0,0 +1,31 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## + +def add(left, right): + return left + right; + +def subtract(left, right): + return left - right; + +def multiply(left, right): + return left * right; + +def divide(left, right): + return left / right; \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/derivedParameters/functions/viirs/__init__.py b/cave/com.raytheon.uf.viz.npp.viirs/localization/derivedParameters/functions/viirs/__init__.py new file mode 100644 index 0000000000..5444413247 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/derivedParameters/functions/viirs/__init__.py @@ -0,0 +1,21 @@ +## +# This software was developed and / or modified by Raytheon Company, +# pursuant to Contract DG133W-05-CQ-1067 with the US Government. +# +# U.S. EXPORT CONTROLLED TECHNICAL DATA +# This software product contains export-restricted data whose +# export/transfer/disclosure is restricted by U.S. law. Dissemination +# to non-U.S. persons whether in the United States or abroad requires +# an export license or other authorization. +# +# Contractor Name: Raytheon Company +# Contractor Address: 6825 Pine Street, Suite 340 +# Mail Stop B8 +# Omaha, NE 68106 +# 402.291.0100 +# +# See the AWIPS II Master Rights File ("Master Rights File.pdf") for +# further licensing information. +## + +# init script so Python treats functions folder as a package \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/index.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/index.xml new file mode 100644 index 0000000000..f32af1cde7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/index.xml @@ -0,0 +1,23 @@ + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/nppMenuItems.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/nppMenuItems.xml new file mode 100644 index 0000000000..907dd3c8ce --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/nppMenuItems.xml @@ -0,0 +1,26 @@ + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsBundleItems.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsBundleItems.xml new file mode 100644 index 0000000000..8eb6972ab0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsBundleItems.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsMenuItems.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsMenuItems.xml new file mode 100644 index 0000000000..a8363df496 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsMenuItems.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsRGBBundleItems.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsRGBBundleItems.xml new file mode 100644 index 0000000000..858aad8e66 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/menus/npp/viirs/viirsRGBBundleItems.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/localization/styleRules/viirsImageryStyleRules.xml b/cave/com.raytheon.uf.viz.npp.viirs/localization/styleRules/viirsImageryStyleRules.xml new file mode 100644 index 0000000000..8493123bad --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/localization/styleRules/viirsImageryStyleRules.xml @@ -0,0 +1,70 @@ + + + + + + + + BT + + + C + + -109 + 55 + + NPP/VIIRS/IR Default + + -100 -80 -60 -40 -20 0 20 40 + + + + + + + + Ref + + + + 0 + 1.6 + + NPP/VIIRS/ZA (Vis Default) + + + + + + + Ref + 1.378 + + + + 0 + 0.6 + + NPP/VIIRS/CA (Low Light Vis) + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.npp.viirs/plugin.xml b/cave/com.raytheon.uf.viz.npp.viirs/plugin.xml new file mode 100644 index 0000000000..75b159da9b --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/plugin.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/Activator.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/Activator.java new file mode 100644 index 0000000000..56c0e66960 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/Activator.java @@ -0,0 +1,62 @@ +package com.raytheon.uf.viz.npp.viirs; + +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + public static final IUFStatusHandler statusHandler = UFStatus + .getHandler(Activator.class); + + // The plug-in ID + public static final String PLUGIN_ID = "com.raytheon.uf.viz.satellite.viirs"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * 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; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/VIIRSProductBrowserDefinition.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/VIIRSProductBrowserDefinition.java new file mode 100644 index 0000000000..f1604acebf --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/VIIRSProductBrowserDefinition.java @@ -0,0 +1,68 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs; + +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.npp.viirs.rsc.VIIRSResourceData; +import com.raytheon.uf.viz.productbrowser.AbstractRequestableProductBrowserDataDefinition; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 6, 2011            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSProductBrowserDefinition extends + AbstractRequestableProductBrowserDataDefinition { + + public VIIRSProductBrowserDefinition() { + productName = "viirs"; + displayName = "VIIRS"; + order = new String[] { "pluginName", "region", "channelType", + "wavelength" }; + order = getOrder(); + loadProperties = new LoadProperties(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.productbrowser. + * AbstractRequestableProductBrowserDataDefinition#getResourceData() + */ + @Override + public VIIRSResourceData getResourceData() { + VIIRSResourceData resourceData = new VIIRSResourceData(); + resourceData.setGroupTimeRangeMinutes(30); + return resourceData; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDataCubeAdapter.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDataCubeAdapter.java new file mode 100644 index 0000000000..fa906e4f67 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDataCubeAdapter.java @@ -0,0 +1,298 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.datastorage.Request; +import com.raytheon.uf.common.datastorage.records.IDataRecord; +import com.raytheon.uf.common.pointdata.PointDataContainer; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.catalog.LayerProperty; +import com.raytheon.uf.viz.core.datastructure.CubeUtil; +import com.raytheon.uf.viz.core.datastructure.VizDataCubeException; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter; +import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData; +import com.raytheon.uf.viz.derivparam.library.DerivParamDesc; +import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode; +import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode; +import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode.Dependency; +import com.raytheon.uf.viz.npp.viirs.Activator; +import com.raytheon.uf.viz.npp.viirs.data.VIIRSRequestableData.VIIRSRequest; + +/** + * DataCubeAdapter for viirs + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSDataCubeAdapter extends AbstractDataCubeAdapter { + + private VIIRSDataInventory inventory; + + public VIIRSDataCubeAdapter() { + super(new String[] { VIIRSDataInventory.PLUGIN_NAME }); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.datastructure.DefaultDataCubeAdapter#initInventory + * () + */ + @Override + public void initInventory() { + if (inventory == null) { + try { + VIIRSDataInventory inventory = new VIIRSDataInventory(); + inventory.initTree(new HashMap()); + this.inventory = inventory; + } catch (Exception e) { + Activator.statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.datastructure.DefaultDataCubeAdapter#getInventory + * () + */ + @Override + public Object getInventory() { + return inventory; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter#getRecord + * (com.raytheon.uf.common.dataplugin.PluginDataObject, + * com.raytheon.uf.common.datastorage.Request, java.lang.String) + */ + @Override + public IDataRecord[] getRecord(PluginDataObject pdo, Request req, + String dataset) throws VizDataCubeException { + if (dataset == null) { + dataset = VIIRSDataRecord.getDataSet(0); + } + try { + IDataRecord[] dataRecords = null; + if (pdo instanceof VIIRSRequestableDataRecord) { + VIIRSRequestableDataRecord vrdr = (VIIRSRequestableDataRecord) pdo; + // Put VIIRSSpatialCoverage from pdo in VIIRSRequest and make + // sure data records out of getData are in same coverage + VIIRSRequest request = new VIIRSRequest(req, dataset, + vrdr.getCoverage()); + AbstractRequestableData requestable = vrdr.getRequestableData(); + if (requestable instanceof VIIRSRequestableData) { + dataRecords = ((VIIRSRequestableData) requestable) + .getRawDataValue(request); + } else { + dataRecords = (IDataRecord[]) requestable + .getDataValue(request); + } + } else if (pdo instanceof VIIRSDataRecord) { + VIIRSDataRecord vdr = (VIIRSDataRecord) pdo; + VIIRSRequestableData requester = new VIIRSRequestableData(vdr, + inventory.getParameterLevel(vdr.getParameter())); + dataRecords = getRecord(new VIIRSRequestableDataRecord( + requester, Arrays.asList(vdr)), req, dataset); + } else { + dataRecords = new IDataRecord[] { CubeUtil.retrieveData(pdo, + pdo.getPluginName(), req, dataset) }; + } + return dataRecords; + } catch (VizException e) { + throw new VizDataCubeException("Error requesting viirs data: " + + e.getLocalizedMessage(), e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter#getRecords(java + * .util.List, com.raytheon.uf.common.datastorage.Request, java.lang.String) + */ + @Override + public void getRecords(List objs, Request req, + String dataset) throws VizDataCubeException { + // TODO: Need more advanced synchronizing for derived parameters + for (PluginDataObject pdo : objs) { + pdo.setMessageData(getRecord(pdo, req, dataset)); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter# + * evaluateRequestConstraints(java.util.Map) + */ + @Override + protected List evaluateRequestConstraints( + Map constraints) { + return inventory.evaluateRequestConstraints(constraints); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter#timeAgnosticQuery + * (java.util.Map) + */ + @Override + protected List timeAgnosticQuery( + Map queryTerms) throws VizException { + return inventory.timeAgnosticQuery(queryTerms); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter#getData(com + * .raytheon.uf.viz.core.catalog.LayerProperty, java.util.List) + */ + @Override + protected List getData(LayerProperty property, + List requesters) throws VizException { + List results = new ArrayList(requesters.size()); + for (AbstractRequestableData requester : requesters) { + List baseRecords = new ArrayList(); + findBaseRecords(requester, baseRecords); + results.add(new VIIRSRequestableDataRecord(requester, baseRecords)); + } + return results; + } + + /** + * Recursively searches dependencies for VIIRSRequestableData objects and + * adds records from objects in baseRecords list + * + * @param requester + * @param baseRecords + */ + private void findBaseRecords(AbstractRequestableData requester, + List baseRecords) { + if (requester instanceof VIIRSRequestableData) { + baseRecords.add(((VIIRSRequestableData) requester).getDataRecord()); + } + for (AbstractRequestableData ard : requester.getDependencies()) { + findBaseRecords(ard, baseRecords); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.derivparam.data.AbstractDataCubeAdapter# + * getBaseUpdateConstraints(java.util.Map) + */ + @Override + public List> getBaseUpdateConstraints( + Map constraints) { + List nodes = evaluateRequestConstraints(constraints); + List> baseConstraints = new ArrayList>(); + for (AbstractRequestableNode node : nodes) { + getBaseUpdateConstraints(baseConstraints, node); + } + return baseConstraints; + } + + private void getBaseUpdateConstraints( + List> baseConstraints, + AbstractRequestableNode node) { + + if (node instanceof VIIRSRequestableLevelNode) { + VIIRSRequestableLevelNode viirsNode = (VIIRSRequestableLevelNode) node; + baseConstraints.add(viirsNode.getRequestConstraintMap()); + } else if (node instanceof AbstractDerivedDataNode) { + AbstractDerivedDataNode derivedNode = (AbstractDerivedDataNode) node; + for (Dependency d : derivedNode.getDependencies()) { + getBaseUpdateConstraints(baseConstraints, d.node); + } + } else if (!node.isConstant()) { + // If everything is working correctly than this is dead code, but it is here just in case I missed something. + Activator.statusHandler.handle(Priority.WARN, this.getClass() + .getSimpleName() + + " cannot determine base constraints for " + + node.getClass().getSimpleName()); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter#getPoints(java + * .lang.String, java.lang.String[], java.util.Map) + */ + @Override + public PointDataContainer getPoints(String plugin, String[] parameters, + Map queryParams) throws VizException { + throw new UnsupportedOperationException( + "getPoints is not supported by viirs"); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.datastructure.IDataCubeAdapter#getPoints(java + * .lang.String, java.lang.String[], java.lang.String, java.util.Map) + */ + @Override + public PointDataContainer getPoints(String plugin, String[] parameters, + String levelKey, Map queryParams) + throws VizException { + throw new UnsupportedOperationException( + "getPoints is not supported by viirs"); + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDataInventory.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDataInventory.java new file mode 100644 index 0000000000..9784f2088a --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDataInventory.java @@ -0,0 +1,450 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Deque; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.raytheon.uf.common.comm.CommunicationException; +import com.raytheon.uf.common.dataplugin.level.Level; +import com.raytheon.uf.common.dataplugin.level.LevelFactory; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; +import com.raytheon.uf.common.derivparam.tree.DataTree; +import com.raytheon.uf.common.derivparam.tree.LevelNode; +import com.raytheon.uf.common.derivparam.tree.ParameterNode; +import com.raytheon.uf.common.derivparam.tree.SourceNode; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.alerts.AlertMessage; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.requests.ThriftClient; +import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData; +import com.raytheon.uf.viz.derivparam.inv.AbstractInventory; +import com.raytheon.uf.viz.derivparam.library.DerivParamDesc; +import com.raytheon.uf.viz.derivparam.library.DerivParamField; +import com.raytheon.uf.viz.derivparam.library.DerivParamMethod; +import com.raytheon.uf.viz.derivparam.tree.AbstractDerivedDataNode; +import com.raytheon.uf.viz.derivparam.tree.AbstractRequestableNode; +import com.raytheon.viz.alerts.IAlertObserver; +import com.raytheon.viz.alerts.observers.ProductAlertObserver; + +/** + * Inventory for viirs data + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSDataInventory extends AbstractInventory implements + IAlertObserver { + + private static final IUFStatusHandler statusHandler = UFStatus + .getHandler(VIIRSDataInventory.class); + + public static final String PLUGIN_NAME = "viirs"; + + private static final String PLUGIN_NAME_QUERY = "pluginName"; + + private static final String CHANNEL_TYPE = "channelType"; + + private static final String PARAMETER = "parameter"; + + private static final String WAVELENGTH = "wavelength"; + + private static final String VIIRS_LEVEL_NAME = "EA"; + + private Level entireAtmosphere; + + private Map> wavelengthParameterMap; + + private Map parameterSourceMap; + + private List viirsSources = new ArrayList(); + + private List viirsParameters = new ArrayList(); + + private List viirsLevels = new ArrayList(); + + public VIIRSDataInventory() throws CommunicationException { + entireAtmosphere = LevelFactory.getInstance().getLevel( + VIIRS_LEVEL_NAME, 0.0); + ProductAlertObserver.addObserver(PLUGIN_NAME, this); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.derivparam.inv.AbstractInventory#getAllSources() + */ + @Override + protected Collection getAllSources() { + return viirsSources; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#getAllParameters() + */ + @Override + protected Collection getAllParameters() { + return viirsParameters; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.derivparam.inv.AbstractInventory#getAllLevels() + */ + @Override + protected Collection getAllLevels() { + return viirsLevels; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#createBaseTree() + */ + @Override + protected DataTree createBaseTree() { + wavelengthParameterMap = new HashMap>(); + parameterSourceMap = new HashMap(); + viirsSources = new ArrayList(); + viirsParameters = new ArrayList(); + viirsLevels = new ArrayList(); + DataTree tree = new DataTree(); + DbQueryRequest request = new DbQueryRequest(); + request.addFields(new String[] { CHANNEL_TYPE, WAVELENGTH, PARAMETER }); + request.setDistinct(true); + request.addConstraint(PLUGIN_NAME_QUERY, new RequestConstraint("viirs")); + try { + DbQueryResponse response = (DbQueryResponse) ThriftClient + .sendRequest(request); + String viirsLevel = String.valueOf(entireAtmosphere.getId()); + viirsLevels.add(entireAtmosphere); + for (Map result : response.getResults()) { + String channelType = (String) result.get(CHANNEL_TYPE); + Number wavelength = (Number) result.get(WAVELENGTH); + String parameter = (String) result.get(PARAMETER); + addToTree(tree, channelType, parameter, wavelength, viirsLevel); + } + } catch (VizException e) { + statusHandler + .handle(Priority.PROBLEM, "Error requesting base tree: " + + e.getLocalizedMessage(), e); + } + + return tree; + } + + public void addToTree(DataTree tree, String channelType, String parameter, + Number wavelength, String level) { + Map rcMap = new HashMap(); + rcMap.put(PLUGIN_NAME_QUERY, new RequestConstraint( + VIIRSDataInventory.PLUGIN_NAME)); + rcMap.put(CHANNEL_TYPE, new RequestConstraint(channelType)); + rcMap.put(PARAMETER, new RequestConstraint(parameter)); + + SourceNode source = tree.getSourceNode(channelType); + if (source == null) { + source = new SourceNode(); + source.setValue(channelType); + tree.getSourceNodes().put(channelType, source); + viirsSources.add(channelType); + } + + // Add node for parameter with wavelength and one for just parameter + + // ParameterNode for parameter only: + String parameterName = parameter; + ParameterNode paramNode = source.getChildNode(parameterName); + if (paramNode == null) { + paramNode = new ParameterNode(); + paramNode.setParameterName(parameterName); + paramNode.setValue(parameterName); + source.addChildNode(paramNode); + } + + LevelNode levelNode = paramNode.getChildNode(level); + if (levelNode == null) { + levelNode = new VIIRSRequestableLevelNode( + new HashMap(rcMap)); + levelNode.setValue(level); + paramNode.addChildNode(levelNode); + } + + // ParameterNode for parameter+wavelength + rcMap.put(WAVELENGTH, new RequestConstraint(String.valueOf(wavelength))); + parameterName = VIIRSDynamicParameters.createParameter(wavelength, + parameter); + + paramNode = source.getChildNode(parameterName); + if (paramNode == null) { + paramNode = new ParameterNode(); + paramNode.setParameterName(parameterName); + paramNode.setValue(parameterName); + source.addChildNode(paramNode); + List parameters = wavelengthParameterMap.get(wavelength); + if (parameters == null) { + parameters = new ArrayList(); + wavelengthParameterMap.put(wavelength, parameters); + } + parameters.add(parameter); + viirsParameters.add(parameterName); + parameterSourceMap.put(parameterName, channelType); + } + + levelNode = paramNode.getChildNode(level); + if (levelNode == null) { + levelNode = new VIIRSRequestableLevelNode(rcMap); + levelNode.setValue(level); + paramNode.addChildNode(levelNode); + } + } + + public List evaluateRequestConstraints( + Map constraints) { + List sources = new ArrayList(); + List parameters = extractParameters(constraints); + for (String parameter : parameters) { + // Ensure parameter definition exists for each parameter + VIIRSDynamicParameters.createParameterDefinitions(parameter, this, + sources); + } + RequestConstraint sourceRC = constraints.get(CHANNEL_TYPE); + if (sourceRC != null) { + // Specific source constraint, clear ones from parameters + sources.clear(); + for (String source : getAllSources()) { + if (sourceRC.evaluate(source)) { + sources.add(source); + } + } + } else { + if (sources.size() > 1) { + // Limit to one source, use first + String toUse = sources.get(0); + sources.clear(); + sources.add(toUse); + } + } + List levels = extractLevels(constraints); + try { + return walkTree(null, sources, parameters, levels, true, true, null); + } catch (InterruptedException e) { + } + return new ArrayList(0); + } + + /** + * @param constraints + * @return + */ + private List extractLevels(Map constraints) { + return Arrays.asList(entireAtmosphere); + } + + public Level getParameterLevel(String parameter) { + return entireAtmosphere; + } + + public String getParameterSource(String parameter) { + return parameterSourceMap.get(parameter); + } + + public DerivParamDesc getParameterDescription(String parameter) { + return derParLibrary.get(parameter); + } + + public void addParameterDescription(String parameter, + DerivParamDesc description) { + derParLibrary.put(parameter, description); + } + + /** + * @param constraints + * @return + */ + private List extractParameters( + Map constraints) { + List parameters = new ArrayList(); + RequestConstraint wavelengthRC = constraints.get(WAVELENGTH); + RequestConstraint parameterRC = constraints.get(PARAMETER); + if (parameterRC == null) { + // No parameter, add any base parameters for the wavelength or all + // parameters if no wavelength either + if (wavelengthRC == null) { + parameters.addAll(getAllParameters()); + } else { + for (Number wavelength : wavelengthParameterMap.keySet()) { + if (wavelengthRC.evaluate(wavelength)) { + List params = wavelengthParameterMap + .get(wavelength); + for (String param : params) { + parameters.add(VIIRSDynamicParameters + .createParameter(wavelength, param)); + } + } + } + } + } else { + ConstraintType parameterType = parameterRC.getConstraintType(); + if (parameterType != ConstraintType.EQUALS) { + throw new RuntimeException("ConstriantType of " + parameterType + + " not supported for viirs dynamic parameters"); + } + String parameter = parameterRC.getConstraintValue(); + for (Number wavelength : wavelengthParameterMap.keySet()) { + if (wavelengthRC == null || wavelengthRC.evaluate(wavelength)) { + String combinedParam = VIIRSDynamicParameters + .createParameter(wavelength, parameter); + if (parameters.contains(combinedParam) == false) { + // Add parameter to list + parameters.add(combinedParam); + } + } + } + } + return parameters; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.alerts.IAlertObserver#alertArrived(java.util.Collection) + */ + @Override + public void alertArrived(Collection alertMessages) { + String level = String.valueOf(entireAtmosphere.getId()); + for (AlertMessage message : alertMessages) { + String channelType = (String) message.decodedAlert + .get(CHANNEL_TYPE); + String parameter = (String) message.decodedAlert.get(PARAMETER); + Number wavelength = (Number) message.decodedAlert.get(WAVELENGTH); + addToTree(dataTree, channelType, parameter, wavelength, level); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#timeAgnosticQuery + * (java.util.Map) + */ + @Override + public List timeAgnosticQuery(Map query) + throws VizException { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#getCubeNode(com. + * raytheon.uf.common.derivparam.tree.SourceNode, + * com.raytheon.uf.viz.derivparam.library.DerivParamField, java.util.Deque, + * java.util.Set) + */ + @Override + protected LevelNode getCubeNode(SourceNode sNode, DerivParamField field, + Deque stack, Set nodata) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#getImportNode(com + * .raytheon.uf.viz.derivparam.data.AbstractRequestableData, + * com.raytheon.uf.common.derivparam.tree.SourceNode, + * com.raytheon.uf.viz.derivparam.library.DerivParamDesc, + * com.raytheon.uf.viz.derivparam.library.DerivParamMethod, + * com.raytheon.uf.common.dataplugin.level.Level) + */ + @Override + protected AbstractDerivedDataNode getImportNode( + AbstractRequestableData nodeToImport, SourceNode destSourceNode, + DerivParamDesc desc, DerivParamMethod method, Level level) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#getImportNode(com + * .raytheon.uf.viz.derivparam.tree.AbstractRequestableLevelNode, + * java.lang.String, com.raytheon.uf.common.derivparam.tree.SourceNode, + * com.raytheon.uf.viz.derivparam.library.DerivParamDesc, + * com.raytheon.uf.viz.derivparam.library.DerivParamMethod, + * com.raytheon.uf.common.dataplugin.level.Level) + */ + @Override + protected AbstractDerivedDataNode getImportNode( + AbstractRequestableNode nodeToImport, + String nodeToImportSourceName, SourceNode destSourceNode, + DerivParamDesc desc, DerivParamMethod method, Level level) { + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.inv.AbstractInventory#resolvePluginStaticData + * (com.raytheon.uf.common.derivparam.tree.SourceNode, + * com.raytheon.uf.viz.derivparam.library.DerivParamField, + * com.raytheon.uf.common.dataplugin.level.Level) + */ + @Override + protected Object resolvePluginStaticData(SourceNode sNode, + DerivParamField field, Level level) { + return null; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDynamicParameters.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDynamicParameters.java new file mode 100644 index 0000000000..eba4c10f57 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSDynamicParameters.java @@ -0,0 +1,384 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.data; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.raytheon.uf.viz.derivparam.library.DerivParamDesc; +import com.raytheon.uf.viz.derivparam.library.DerivParamField; +import com.raytheon.uf.viz.derivparam.library.DerivParamMethod; +import com.raytheon.uf.viz.derivparam.library.DerivParamMethod.MethodType; + +/** + * Class for resolving viirs parameters dynamically. Parses parameter as + * expression which may include basic math (+,-,*,/) or simple function calls + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSDynamicParameters { + + private static final String FUNCTION_PREFIX = "viirs."; + + private static enum Operator { + ADD("+", 1, FUNCTION_PREFIX + "Math.add"), SUBTRACT("-", 1, + FUNCTION_PREFIX + "Math.subtract"), MULTIPLY("*", 2, + FUNCTION_PREFIX + "Math.multiply"), DIVIDE("/", 2, + FUNCTION_PREFIX + "Math.divide"); + + private String token; + + private int priority; + + private String function; + + private Operator(String token, int priority, String function) { + this.token = token; + this.priority = priority; + this.function = function; + } + } + + private static class Node { + + protected String token; + + protected Node(String token) { + this.token = token; + } + + protected String getNodeName() { + return token; + } + + } + + private static class OperatorNode extends FunctionNode { + + protected Operator operator; + + protected Node leftChild; + + protected Node rightChild; + + protected OperatorNode(String token, Operator operator) { + super(token); + this.function = operator.function; + this.operator = operator; + } + + @Override + public int getPriority() { + return operator.priority; + } + + @Override + public void setChildren(Stack stack) { + this.rightChild = stack.pop(); + this.leftChild = stack.pop(); + } + + @Override + public Collection getChildren() { + return Arrays.asList(leftChild, rightChild); + } + + @Override + protected String getNodeName() { + return leftChild.getNodeName() + operator.token + + rightChild.getNodeName(); + } + + } + + private static class FunctionNode extends Node { + + private static final String FUNCTION_FORMAT = "%s(%s)"; + + protected String function; + + protected Node parameter; + + protected FunctionNode(String token) { + super(token.endsWith(OPEN_PAREN) ? token.substring(0, + token.length() - 1) : token); + this.function = FUNCTION_PREFIX + this.token; + } + + public int getPriority() { + return Integer.MAX_VALUE; + } + + public void setChildren(Stack stack) { + this.parameter = stack.pop(); + } + + protected String getFunctionName() { + return function; + } + + @Override + protected String getNodeName() { + return String.format(FUNCTION_FORMAT, token, + parameter.getNodeName()); + } + + public Collection getChildren() { + return Arrays.asList(parameter); + } + + } + + private static final Map operatorMap = new HashMap(); + + static { + for (Operator op : Operator.values()) { + operatorMap.put(op.token, op); + } + } + + private static final String OPEN_PAREN = "("; + + private static final String CLOSE_PAREN = ")"; + + private static final String WAVELENGTH_PARAMETER_GROUP = "((\\d+\\.\\d+)([a-zA-Z]+))"; + + private static final Pattern OPERATOR_PATTERN = Pattern + .compile("([ ]*[\\+/\\-\\*\\(\\)][ ]*)"); + + /** Pattern for a function, matches 'functionName(' group(1) is functionName */ + private static final Pattern FUNCTION_PATTERN = Pattern + .compile("(([a-zA-Z])+\\()"); + + /** Tokenizes a parameter expression for parsing */ + private static final Pattern PARAMETER_EXPRESSION_PATTERN = Pattern + .compile(FUNCTION_PATTERN.pattern() + "|([a-zA-Z0-9\\.]+)|" + + OPERATOR_PATTERN.pattern()); + + private static final Pattern WAVELENGTH_PARAMETER_PATTERN = Pattern + .compile("^" + WAVELENGTH_PARAMETER_GROUP + "$"); + + private static final String WAVELENGTH_PARAMTER_FORMAT = "%s%s"; + + /** + * Creates derived parameter descriptions for the viirs dynamic parameter + * + * @param parameter + * @param descriptions + */ + public static void createParameterDefinitions(String parameter, + VIIRSDataInventory inventory, List parameterSources) { + Node astRoot = createExpressionTree(parameter); + createParameterDefinitions(astRoot, inventory, parameterSources); + } + + private static void createParameterDefinitions(Node astNode, + VIIRSDataInventory inventory, List parameterSources) { + String nodeName = astNode.getNodeName(); + String nodeSource = inventory.getParameterSource(nodeName); + if (astNode instanceof FunctionNode) { + FunctionNode node = (FunctionNode) astNode; + + // Process children nodes + Collection children = node.getChildren(); + for (Node child : children) { + // Ensure we have definition for child + createParameterDefinitions(child, inventory, parameterSources); + } + + DerivParamDesc desc = inventory.getParameterDescription(nodeName); + if (desc == null) { + // Create description object for function + desc = new DerivParamDesc(); + desc.setAbbreviation(nodeName); + desc.setName(nodeName); + + // Create method object for function desc + DerivParamMethod method = new DerivParamMethod(); + method.setName(node.getFunctionName()); + method.setMethodType(MethodType.PYTHON); + desc.addMethod(method); + + // Process children nodes + for (Node child : children) { + // Create field for child in our definition method + DerivParamField field = new DerivParamField(); + String fieldName = child.getNodeName(); + field.setParam(fieldName); + field.setValidSource(inventory + .getParameterSource(fieldName)); + method.addField(field); + } + + inventory.addParameterDescription(nodeName, desc); + } + } + if (nodeSource != null + && parameterSources.contains(nodeSource) == false) { + parameterSources.add(nodeSource); + } + } + + /** + * Takes a parameter/wavelength combo and creates a single parameter with + * wavelength embedded in it + * + * @param wavelength + * @param parameter + * @return + */ + public static String createParameter(Number wavelength, String parameter) { + String[] parts = parseExpression(parameter); + StringBuffer buffer = new StringBuffer(); + for (String part : parts) { + String tmp = part.trim(); + if (!OPERATOR_PATTERN.matcher(tmp).matches() + && !FUNCTION_PATTERN.matcher(tmp).matches()) { + // Not operator, not function + Matcher paramCheck = WAVELENGTH_PARAMETER_PATTERN.matcher(part); + if (paramCheck.find() == false) { + // Does't have a wavelength on parameter, add it + part = String.format(WAVELENGTH_PARAMTER_FORMAT, + wavelength, tmp); + } + } + buffer.append(part); + } + + return buffer.toString(); + } + + /** + * Creates an abstract syntax tree from the parameter expression. + * + * @param expression + * @return + */ + private static Node createExpressionTree(String expression) { + Stack functionStack = new Stack(); + Stack treeStack = new Stack(); + String[] parts = parseExpression(expression); + for (int i = 0; i < parts.length; ++i) { + String token = parts[i].trim(); + if (isGroupStart(token)) { + if (token.length() > 1) { + // Start of function + functionStack.push(new FunctionNode(token)); + } else { + // Start of paren group + functionStack.push(null); + } + } else if (isGroupEnd(token)) { + // End of group/function, reduce until we find matching paren + while (functionStack.peek() != null) { + boolean endOfFunc = (functionStack.peek() instanceof OperatorNode) == false; + reduce(functionStack, treeStack); + if (endOfFunc) { + break; + } + } + if (functionStack.isEmpty() == false + && functionStack.peek() == null) { + // Pop matching paren, didn't end with function start + functionStack.pop(); + } + } else if (OPERATOR_PATTERN.matcher(token).matches()) { + // Operator (+-/*), get operator + Operator operator = operatorMap.get(token); + OperatorNode op = new OperatorNode(token, operator); + while (functionStack.isEmpty() == false) { + FunctionNode next = functionStack.peek(); + if (next instanceof OperatorNode + && op.getPriority() < next.getPriority()) { + reduce(functionStack, treeStack); + } else { + // Done reducing + break; + } + } + functionStack.push(op); + } else if (WAVELENGTH_PARAMETER_PATTERN.matcher(token).matches()) { + treeStack.push(new Node(token)); + } else { + System.err.println("Error parsing token: " + token); + } + } + while (functionStack.isEmpty() == false) { + reduce(functionStack, treeStack); + } + return treeStack.peek(); + } + + private static boolean isGroupStart(String token) { + return token.endsWith(OPEN_PAREN); + } + + private static boolean isGroupEnd(String token) { + return token.equals(CLOSE_PAREN); + } + + /** + * Removes from the operator stack, sets left/right then adds to tree stack + * + * @param functionStack + * @param treeStack + */ + private static void reduce(Stack functionStack, + Stack treeStack) { + FunctionNode N = functionStack.pop(); + N.setChildren(treeStack); + treeStack.push(N); + } + + /** + * Splits an expression by function/parameter/math operators + * + * @param expression + * @return + */ + private static String[] parseExpression(String expression) { + List parts = new ArrayList(); + Matcher math = PARAMETER_EXPRESSION_PATTERN.matcher(expression); + while (math.find()) { + parts.add(math.group()); + } + return parts.toArray(new String[parts.size()]); + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableData.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableData.java new file mode 100644 index 0000000000..2ba431e40a --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableData.java @@ -0,0 +1,343 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.data; + +import java.awt.Point; +import java.awt.Rectangle; +import java.util.Map; + +import javax.measure.converter.UnitConverter; +import javax.measure.unit.Unit; + +import org.geotools.coverage.grid.GeneralGridGeometry; +import org.geotools.coverage.grid.GridEnvelope2D; +import org.geotools.coverage.grid.GridGeometry2D; +import org.opengis.geometry.Envelope; + +import com.raytheon.uf.common.dataplugin.level.Level; +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSSpatialCoverage; +import com.raytheon.uf.common.datastorage.DataStoreFactory; +import com.raytheon.uf.common.datastorage.IDataStore; +import com.raytheon.uf.common.datastorage.Request; +import com.raytheon.uf.common.datastorage.records.FloatDataRecord; +import com.raytheon.uf.common.datastorage.records.IDataRecord; +import com.raytheon.uf.common.datastorage.records.ShortDataRecord; +import com.raytheon.uf.common.geospatial.interpolation.BilinearInterpolation; +import com.raytheon.uf.common.geospatial.interpolation.GridDownscaler; +import com.raytheon.uf.common.geospatial.interpolation.GridReprojection; +import com.raytheon.uf.common.geospatial.interpolation.data.FloatArrayWrapper; +import com.raytheon.uf.common.geospatial.interpolation.data.ShortArrayWrapper; +import com.raytheon.uf.common.geospatial.interpolation.data.UnsignedShortArrayWrapper; +import com.raytheon.uf.viz.core.HDF5Util; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData; + +/** + * Object capable of requesting VIIRS data for base or derived displays. Can + * also reproject into different coverages + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 19, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSRequestableData extends AbstractRequestableData { + + /** + * The data request object, bounds of request, full coverage, and dataset to + * request + */ + public static class VIIRSRequest { + public final Request request; + + public final String dataset; + + public final VIIRSSpatialCoverage coverage; + + public VIIRSRequest(Request request, String dataset, + VIIRSSpatialCoverage coverage) { + this.request = request; + this.dataset = dataset; + this.coverage = coverage; + } + } + + /** Data record this object requests for */ + private VIIRSDataRecord dataRecord; + + public VIIRSRequestableData(VIIRSDataRecord dataRecord, Level level) { + this.dataRecord = dataRecord; + setDataTime(dataRecord.getDataTime()); + setLevel(level); + setParameter(dataRecord.getParameter()); + setParameterName(VIIRSDynamicParameters.createParameter( + dataRecord.getWavelength(), dataRecord.getParameter())); + setSource(dataRecord.getChannelType()); + setUnit(Unit.ONE); + } + + /** + * Gets the raw data records without converting to floats/applying scale and + * offset. Will ensure returned data is projected into request's coverage. + * Can be directly called if data is desired to stay in "short" format. + * Otherwise calling {@link #getDataValue(Object)} will cause data to be + * converted to "float" by having scale/offset applied + * + * @param request + * @return + * @throws VizException + */ + public IDataRecord[] getRawDataValue(VIIRSRequest request) + throws VizException { + IDataStore store = DataStoreFactory.getDataStore(HDF5Util + .findHDF5Location(dataRecord)); + try { + VIIRSSpatialCoverage recordCoverage = dataRecord.getCoverage(); + VIIRSSpatialCoverage requestCoverage = request.coverage; + if (recordCoverage.equals(requestCoverage) == false) { + // Data coverages are different, reprojection is required + GridGeometry2D requestGeometry = requestCoverage + .getGridGeometry(); + GridGeometry2D recordGeometry = recordCoverage + .getGridGeometry(); + + // Grab the downscale rectangles for the geomerties + Rectangle[] requestSizes = GridDownscaler + .getDownscaleSizes(requestGeometry); + Rectangle[] recordSizes = GridDownscaler + .getDownscaleSizes(recordGeometry); + + // Figure out what level we are requesting for + int length = Math.min(requestSizes.length, recordSizes.length); + int level; + for (level = 0; level < length; ++level) { + if (VIIRSDataRecord.getDataSet(level).equals( + request.dataset)) { + break; + } + } + Rectangle requestLevelRect = requestSizes[level]; + Rectangle recordLevelRect = recordSizes[level]; + + // Calculate ratio based on request level sizes + double diffRatioX = recordLevelRect.getWidth() + / requestLevelRect.getWidth(); + double diffRatioY = recordLevelRect.getHeight() + / requestLevelRect.getHeight(); + + GeneralGridGeometry requestSliceGeometry = null; + GeneralGridGeometry recordSliceGeometry = null; + + Request req = request.request; + Request recordRequest = req; + switch (request.request.getType()) { + case POINT: + Point[] points = req.getPoints(); + Point[] newPoints = new Point[points.length]; + for (int i = 0; i < points.length; ++i) { + newPoints[i] = new Point((int) Math.max(points[i].x + * diffRatioX, requestLevelRect.width - 1), + (int) Math.max(points[i].x * diffRatioX, + requestLevelRect.height - 1)); + } + recordRequest = Request.buildPointRequest(newPoints); + break; + case SLAB: + int[] min = req.getMinIndexForSlab(); + int[] max = req.getMaxIndexForSlab(); + GridEnvelope2D reqGrid = new GridEnvelope2D(0, 0, max[0] + - min[0], max[1] - min[1]); + requestSliceGeometry = new GridGeometry2D(reqGrid, + (Envelope) requestGeometry.gridToWorld(reqGrid)); + recordRequest = Request.buildSlab( + new int[] { (int) (min[0] * diffRatioX), + (int) (min[1] * diffRatioY) }, + new int[] { + (int) Math.min(max[0] * diffRatioX, + recordLevelRect.getMaxX()), + (int) Math.min(max[1] * diffRatioY, + recordLevelRect.getMaxY()) }); + min = recordRequest.getMinIndexForSlab(); + max = recordRequest.getMaxIndexForSlab(); + GridEnvelope2D recGrid = new GridEnvelope2D(0, 0, max[0] + - min[0], max[1] - min[1]); + recordSliceGeometry = new GridGeometry2D(recGrid, + (Envelope) recordGeometry.gridToWorld(recGrid)); + break; + case ALL: + requestSliceGeometry = requestGeometry; + recordSliceGeometry = recordGeometry; + break; + } + + IDataRecord record = store.retrieve(dataRecord.getDataURI(), + request.dataset, recordRequest); + if (requestSliceGeometry != null && recordSliceGeometry != null) { + // Slice geometries are set, we need to reproject into + // request space + double noData = Double.NaN; + if (record.getDataAttributes().containsKey( + VIIRSDataRecord.MISSING_VALUE_ID)) { + noData = ((Number) record.getDataAttributes().get( + VIIRSDataRecord.MISSING_VALUE_ID)) + .doubleValue(); + } + + GridReprojection reprojection = new GridReprojection( + recordSliceGeometry, requestSliceGeometry); + UnsignedShortArrayWrapper dest = new UnsignedShortArrayWrapper( + requestSliceGeometry); + dest.setFillValue(noData); + UnsignedShortArrayWrapper source = new UnsignedShortArrayWrapper( + ((ShortDataRecord) record).getShortData(), + recordSliceGeometry); + source.setFillValue(noData); + reprojection.reprojectedGrid(new BilinearInterpolation(), + source, dest); + + ShortDataRecord scaled = new ShortDataRecord( + record.getName(), record.getGroup(), + dest.getArray()); + copyRecord(scaled, record); + // set correct sizes after copying attributes + scaled.setIntSizes(new int[] { + requestSliceGeometry.getGridRange().getSpan(0), + requestSliceGeometry.getGridRange().getSpan(1) }); + record = scaled; + } + return new IDataRecord[] { record }; + } else { + return new IDataRecord[] { store.retrieve( + dataRecord.getDataURI(), request.dataset, + request.request) }; + } + } catch (Exception e) { + throw new VizException("Error retrieving viirs data: " + + e.getLocalizedMessage(), e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.derivparam.data.AbstractRequestableData#getDataValue + * (java.lang.Object) + */ + @Override + public IDataRecord[] getDataValue(Object arg) throws VizException { + VIIRSRequest request = (VIIRSRequest) arg; + // Get raw data + IDataRecord[] records = getRawDataValue(request); + for (int i = 0; i < records.length; ++i) { + IDataRecord record = records[i]; + Map attrs = record.getDataAttributes(); + double noDataValue = Double.NaN; + if (attrs.containsKey(VIIRSDataRecord.MISSING_VALUE_ID)) { + // Replace no data value with NaN while assigning noDataValue + noDataValue = ((Number) attrs.put( + VIIRSDataRecord.MISSING_VALUE_ID, noDataValue)) + .doubleValue(); + } + + Unit dataUnit = Unit.ONE; + // Remove scale/offset since we are applying them now + Float offset = (Float) attrs.remove(VIIRSDataRecord.OFFSET_ID); + Float scale = (Float) attrs.remove(VIIRSDataRecord.SCALE_ID); + + if (offset != null && offset != 0.0) { + dataUnit = dataUnit.plus(offset); + } + if (scale != null && scale != 0.0) { + dataUnit = dataUnit.times(scale); + } + + long[] sizes = record.getSizes(); + int width = (int) sizes[0], height = 1; + if (sizes.length > 1) { + height = (int) sizes[1]; + } + float[] floatData = new float[width * height]; + final UnitConverter converter = dataUnit.getConverterTo(Unit.ONE); + FloatArrayWrapper destination = new FloatArrayWrapper(floatData, + width, height) { + @Override + public void setDataValueInternal(double dataValue, int index) { + // Apply unit converter for each value + super.setDataValueInternal(converter.convert(dataValue), + index); + } + }; + destination.setFillValue(Float.NaN); + UnsignedShortArrayWrapper source = new UnsignedShortArrayWrapper( + ((ShortDataRecord) record).getShortData(), width, height); + source.setFillValue(noDataValue); + + // For each point, set in destination + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + destination.setDataValue(source.getDataValue(x, y), x, y); + } + } + + // Create float data record from converted data + FloatDataRecord fdr = new FloatDataRecord(record.getName(), + record.getGroup(), floatData); + copyRecord(fdr, record); + records[i] = fdr; + } + return records; + } + + /** + * @return the dataRecord + */ + public VIIRSDataRecord getDataRecord() { + return dataRecord; + } + + /** + * Copies one {@link IDataRecord} into another + * + * @param to + * @param from + */ + public static void copyRecord(IDataRecord to, IDataRecord from) { + to.setCorrelationObject(from.getCorrelationObject()); + to.setDataAttributes(from.getDataAttributes()); + to.setDimension(from.getDimension()); + to.setFillValue(from.getFillValue()); + to.setMaxChunkSize(from.getMaxChunkSize()); + to.setMaxSizes(from.getMaxSizes()); + to.setMinIndex(from.getMinIndex()); + to.setProperties(from.getProperties()); + to.setSizes(from.getSizes()); + } +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableDataRecord.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableDataRecord.java new file mode 100644 index 0000000000..ccb599e46a --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableDataRecord.java @@ -0,0 +1,131 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.data; + +import java.util.Collection; + +import com.raytheon.uf.common.dataplugin.PluginException; +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 30, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSRequestableDataRecord extends VIIRSDataRecord { + + private static final long serialVersionUID = 482141143796775377L; + + private AbstractRequestableData requestableData; + + public VIIRSRequestableDataRecord(AbstractRequestableData requestableData, + Collection baseRecords) { + int i = 0; + Integer lastChannel = null; + boolean channelsSame = true; + Double lastWavelength = null; + boolean wavelengthsSame = true; + Integer lastHdf5FileId = null; + boolean hdf5FileIdsSame = true; + String lastChannelType = null; + boolean channelTypeSame = true; + // We will build ourself from our base records, anything that isn't + // consistent among all records is not set + for (VIIRSDataRecord record : baseRecords) { + if (i == 0) { + // Set common things from first record + setRegion(record.getRegion()); + setDataTime(record.getDataTime()); + setLevels(record.getLevels()); + setCoverage(record.getCoverage()); + + // Set potentially varying items + lastChannelType = record.getChannelType(); + lastChannel = record.getChannel(); + lastWavelength = record.getWavelength(); + lastHdf5FileId = record.getHdfFileId(); + } else { + if (channelTypeSame + && equals(lastChannelType, record.getChannelType()) == false) { + channelTypeSame = false; + } + if (channelsSame + && equals(lastChannel, record.getChannel()) == false) { + channelsSame = false; + } + if (wavelengthsSame + && equals(lastWavelength, record.getWavelength()) == false) { + wavelengthsSame = false; + } + if (hdf5FileIdsSame + && equals(lastHdf5FileId, record.getHdfFileId()) == false) { + hdf5FileIdsSame = false; + } + if (record.getLevels() < getLevels()) { + // We want minimum levels of all base records + setLevels(record.getLevels()); + setCoverage(record.getCoverage()); + } + } + ++i; + } + if (channelTypeSame) { + setChannelType(lastChannelType); + } + if (channelsSame) { + setChannel(lastChannel); + } + if (wavelengthsSame) { + setWavelength(lastWavelength); + } + if (hdf5FileIdsSame) { + setHdfFileId(lastHdf5FileId); + } + setParameter(requestableData.getParameter()); + try { + constructDataURI(); + } catch (PluginException e) { + throw new RuntimeException("Error constructing dataURI: " + + e.getLocalizedMessage(), e); + } + this.requestableData = requestableData; + } + + public AbstractRequestableData getRequestableData() { + return requestableData; + } + + private static boolean equals(Object o1, Object o2) { + return (o1 == o2) || (o1 != null && o1.equals(o2)); + } +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableLevelNode.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableLevelNode.java new file mode 100644 index 0000000000..f3d454ff4b --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/data/VIIRSRequestableLevelNode.java @@ -0,0 +1,174 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.data; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequest; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.dataquery.responses.DbQueryResponse; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.derivparam.data.AbstractRequestableData; +import com.raytheon.uf.viz.derivparam.inv.TimeAndSpace; +import com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode; + +/** + * VIIRS Requestable level node + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jan 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSRequestableLevelNode extends AbstractBaseDataNode { + + private Map requestConstraints; + + /** + * @param requestConstraints + */ + public VIIRSRequestableLevelNode( + Map requestConstraints) { + this.requestConstraints = requestConstraints; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime + * result + + ((requestConstraints == null) ? 0 : requestConstraints + .hashCode()); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + VIIRSRequestableLevelNode other = (VIIRSRequestableLevelNode) obj; + if (requestConstraints == null) { + if (other.requestConstraints != null) + return false; + } else if (!requestConstraints.equals(other.requestConstraints)) + return false; + return true; + } + + public Map getRequestConstraintMap() { + return requestConstraints; + } + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode#getAvailabilityRequest() + */ + @Override + public DbQueryRequest getAvailabilityRequest() { + DbQueryRequest request = new DbQueryRequest(); + request.setEntityClass(VIIRSDataRecord.class.getName()); + request.addRequestField("dataTime"); + request.setDistinct(true); + request.setConstraints(requestConstraints); + return request; + } + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode#getDataRequest(java.util.Map, java.util.Set) + */ + @Override + public DbQueryRequest getDataRequest( + Map originalConstraints, + Set availability) { + Map constraints = new HashMap( + originalConstraints); + constraints.putAll(requestConstraints); + constraints.put("pluginName", new RequestConstraint("viirs")); + DbQueryRequest request = new DbQueryRequest(); + request.setConstraints(constraints); + request.setEntityClass(VIIRSDataRecord.class); + return request; + } + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode#getAvailability(java.lang.Object) + */ + @Override + public Set getAvailability(Object response) + throws VizException { + Set result = new HashSet(); + DbQueryResponse dbresponse = (DbQueryResponse) response; + for (Map map : dbresponse.getResults()) { + DataTime time = (DataTime) map.get("dataTime"); + + result.add(new TimeAndSpace(time)); + } + return result; + } + + /* (non-Javadoc) + * @see com.raytheon.uf.viz.derivparam.tree.AbstractBaseDataNode#getData(java.util.Map, java.util.Set, java.lang.Object) + */ + @Override + public Set getData( + Map orignalConstraints, + Set availability, Object response) + throws VizException { + DbQueryResponse queryResponse = (DbQueryResponse) response; + List> results = queryResponse.getResults(); + Set data = new HashSet( + results.size()); + for (Map result : results) { + data.add(new VIIRSRequestableData((VIIRSDataRecord) result + .get(null), getLevel())); + } + return data; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSDataCallback.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSDataCallback.java new file mode 100644 index 0000000000..80e11bd79e --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSDataCallback.java @@ -0,0 +1,153 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.rsc; + +import java.awt.Rectangle; +import java.nio.Buffer; +import java.nio.FloatBuffer; +import java.nio.ShortBuffer; + +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.common.datastorage.Request; +import com.raytheon.uf.common.datastorage.records.FloatDataRecord; +import com.raytheon.uf.common.datastorage.records.IDataRecord; +import com.raytheon.uf.common.datastorage.records.ShortDataRecord; +import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback; +import com.raytheon.uf.viz.core.datastructure.DataCubeContainer; +import com.raytheon.uf.viz.core.exception.VizException; + +/** + * VIIRS Colormap data callback, requests data for VIIRSDataRecord + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 30, 2011            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSDataCallback implements IColorMapDataRetrievalCallback { + + private VIIRSDataRecord dataRecord; + + private int level; + + private Rectangle dataArea; + + public VIIRSDataCallback(VIIRSDataRecord dataRecord, int level, + Rectangle dataArea) { + this.dataRecord = dataRecord; + this.level = level; + this.dataArea = dataArea; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback#getColorMapData + * () + */ + @Override + public ColorMapData getColorMapData() throws VizException { + try { + IDataRecord[] records = DataCubeContainer.getDataRecord(dataRecord, + Request.buildSlab(new int[] { dataArea.x, dataArea.y }, + new int[] { dataArea.x + dataArea.width, + dataArea.y + dataArea.height }), + VIIRSDataRecord.getDataSet(level)); + IDataRecord rawData = records[0]; + if (rawData instanceof ShortDataRecord) { + Buffer shortData = ShortBuffer.wrap(((ShortDataRecord) rawData) + .getShortData()); + return new ColorMapData(shortData, new int[] { + (int) rawData.getSizes()[0], + (int) rawData.getSizes()[1] }, + ColorMapDataType.UNSIGNED_SHORT); + } else if (rawData instanceof FloatDataRecord) { + Buffer floatData = FloatBuffer.wrap(((FloatDataRecord) rawData) + .getFloatData()); + return new ColorMapData(floatData, new int[] { + (int) rawData.getSizes()[0], + (int) rawData.getSizes()[1] }, ColorMapDataType.FLOAT); + } else { + throw new VizException("Could not handle IDataRecord: " + + rawData); + } + } catch (Throwable t) { + throw new VizException("Error requesting viirs slab: " + + t.getLocalizedMessage(), t); + } + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((dataArea == null) ? 0 : dataArea.hashCode()); + result = prime * result + + ((dataRecord == null) ? 0 : dataRecord.hashCode()); + result = prime * result + level; + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + VIIRSDataCallback other = (VIIRSDataCallback) obj; + if (dataArea == null) { + if (other.dataArea != null) + return false; + } else if (!dataArea.equals(other.dataArea)) + return false; + if (dataRecord == null) { + if (other.dataRecord != null) + return false; + } else if (!dataRecord.equals(other.dataRecord)) + return false; + if (level != other.level) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSResource.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSResource.java new file mode 100644 index 0000000000..336d8d6b89 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSResource.java @@ -0,0 +1,626 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.rsc; + +import java.text.DecimalFormat; +import java.text.ParsePosition; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.measure.converter.UnitConverter; +import javax.measure.unit.Unit; +import javax.measure.unit.UnitFormat; + +import org.geotools.coverage.grid.GeneralGridGeometry; +import org.opengis.referencing.crs.CoordinateReferenceSystem; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.common.datastorage.Request; +import com.raytheon.uf.common.datastorage.records.IDataRecord; +import com.raytheon.uf.common.datastorage.records.ShortDataRecord; +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.TimeRange; +import com.raytheon.uf.viz.core.DrawableImage; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IGraphicsTarget.RasterMode; +import com.raytheon.uf.viz.core.IMesh; +import com.raytheon.uf.viz.core.PixelCoverage; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.core.datastructure.DataCubeContainer; +import com.raytheon.uf.viz.core.drawables.ColorMapLoader; +import com.raytheon.uf.viz.core.drawables.ColorMapParameters; +import com.raytheon.uf.viz.core.drawables.IImage; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension.ImageProvider; +import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.map.IMapDescriptor; +import com.raytheon.uf.viz.core.map.IMapMeshExtension; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability; +import com.raytheon.uf.viz.core.style.LabelingPreferences; +import com.raytheon.uf.viz.core.style.StyleManager; +import com.raytheon.uf.viz.core.style.StyleManager.StyleType; +import com.raytheon.uf.viz.core.style.StyleRule; +import com.raytheon.uf.viz.core.tile.Tile; +import com.raytheon.uf.viz.core.tile.TileSetRenderable; +import com.raytheon.uf.viz.core.tile.TileSetRenderable.TileImageCreator; +import com.raytheon.uf.viz.npp.viirs.style.VIIRSDataRecordCriteria; +import com.raytheon.viz.core.style.image.DataScale; +import com.raytheon.viz.core.style.image.ImagePreferences; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * NPP VIIRS resource. Responsible for drawing a single color band. + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 30, 2011            mschenke    Initial creation
+ * Feb 21, 2012 #30        mschenke    Fixed sampling issue
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSResource extends + AbstractVizResource implements + IResourceDataChanged, ImageProvider { + + protected static final IUFStatusHandler statusHandler = UFStatus + .getHandler(VIIRSResource.class); + + public static final String DATA_KEY = "dataValue"; + + public static final String UNIT_KEY = "unit"; + + private static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("0.00"); + + private class VIIRSTileImageCreator implements TileImageCreator { + + private VIIRSDataRecord record; + + private VIIRSTileImageCreator(VIIRSDataRecord record) { + this.record = record; + } + + @Override + public DrawableImage createTileImage(IGraphicsTarget target, Tile tile, + GeneralGridGeometry targetGeometry) throws VizException { + IImage image = target + .getExtension(IColormappedImageExtension.class) + .initializeRaster( + new VIIRSDataCallback(record, tile.tileLevel, + tile.getRectangle()), + getCapability(ColorMapCapability.class) + .getColorMapParameters()); + IMesh mesh = target.getExtension(IMapMeshExtension.class) + .constructMesh(tile.tileGeometry, targetGeometry); + return new DrawableImage(image, new PixelCoverage(mesh), + RasterMode.ASYNCHRONOUS); + } + } + + /** + * Every {@link VIIRSDataRecord} will have a corresponding RecordData object + */ + private static class RecordData { + + /** Indicates if data intersects current descriptor */ + private boolean intersects = false; + + /** Indicates if the {@link #tileSet} needs to be projected */ + private boolean project = true; + + /** Renderable for the data record */ + private TileSetRenderable tileSet; + + } + + /** + * Map for data records to renderable data, synchronized on for painting, + * disposing, adding, and removing + */ + private Map dataRecordMap; + + private String name; + + /** + * @param resourceData + * @param loadProperties + */ + public VIIRSResource(VIIRSResourceData resourceData, + LoadProperties loadProperties, List initialRecords) { + super(resourceData, loadProperties); + dataRecordMap = new LinkedHashMap(); + resourceData.addChangeListener(this); + dataTimes = new ArrayList(); + for (VIIRSDataRecord record : initialRecords) { + dataRecordMap.put(record, null); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getName() + */ + @Override + public String getName() { + if (name == null) { + return "NPP VIIRS"; + } + return name; + } + + /** + * Add a data record to be displayed. Should be synchronized on + * {@link #dataMap} when called + * + * @param dataRecord + * @return false if record should be discarded + * @throws VizException + * @throws Exception + */ + protected void addRecord(VIIRSDataRecord dataRecord) throws VizException { + if (name == null) { + initializeFirstRecord(dataRecord); + } + + RecordData data = dataRecordMap.get(dataRecord); + if (data == null) { + // New record + data = new RecordData(); + data.tileSet = new TileSetRenderable( + getCapability(ImagingCapability.class), dataRecord + .getCoverage().getGridGeometry(), + new VIIRSTileImageCreator(dataRecord), + dataRecord.getLevels(), 256); + dataRecordMap.put(dataRecord, data); + } + + // Make sure record intersects map + data.intersects = intersects(dataRecord); + } + + private boolean intersects(VIIRSDataRecord dataRecord) { + // Make sure spatial record intersects map + PixelCoverage dataCoverage = descriptor.worldToPixel(dataRecord + .getCoverage().getEnvelope().getEnvelopeInternal()); + return dataCoverage.intersects(new PixelExtent(descriptor + .getGridGeometry().getGridRange())); + } + + /** + * First record was added, initialize any fields that require information + * from a record + * + * @param dataRecord + * @throws VizException + */ + protected void initializeFirstRecord(VIIRSDataRecord dataRecord) + throws VizException { + name = "NPP VIIRS"; + // First record, process name and parameters + if (dataRecord.getChannelType() != null) { + name += " " + dataRecord.getChannelType(); + } + String parameter = dataRecord.getParameter(); + if (dataRecord.getWavelength() != null) { + parameter = dataRecord.getWavelength() + parameter; + } + name += " " + parameter; + + // Get style rule preferences + StyleRule styleRule = StyleManager.getInstance().getStyleRule( + StyleType.IMAGERY, new VIIRSDataRecordCriteria(dataRecord)); + ImagePreferences preferences = null; + if (styleRule != null) { + preferences = (ImagePreferences) styleRule.getPreferences(); + } + + // Create colormap parameters + ColorMapParameters colorMapParameters = getCapability( + ColorMapCapability.class).getColorMapParameters(); + if (colorMapParameters == null) { + colorMapParameters = new ColorMapParameters(); + } + + // Setup colormap + if (colorMapParameters.getColorMap() == null) { + // None set, set name and load + String name = colorMapParameters.getColorMapName(); + if (name == null) { + if (preferences != null) { + // check preference + name = preferences.getDefaultColormap(); + } + if (name == null) { + // no preference, absolute default colormap + name = "NPP/VIIRS/IR Default"; + } + } + colorMapParameters.setColorMap(ColorMapLoader.loadColorMap(name)); + } + + // Setup units for display and data + Unit displayUnit = Unit.ONE; + if (preferences != null) { + if (preferences.getDisplayUnits() != null) { + displayUnit = preferences.getDisplayUnits(); + } + } + Unit dataUnit = Unit.ONE; + + try { + IDataRecord record = DataCubeContainer.getDataRecord(dataRecord, + Request.buildPointRequest(new java.awt.Point(0, 0)), + VIIRSDataRecord.getDataSet(0))[0]; + Map attrs = record.getDataAttributes(); + if (attrs != null) { + Float offset = (Float) attrs.get(VIIRSDataRecord.OFFSET_ID); + Float scale = (Float) attrs.get(VIIRSDataRecord.SCALE_ID); + String unitStr = (String) attrs.get(VIIRSDataRecord.UNIT_ID); + if (attrs.containsKey(VIIRSDataRecord.MISSING_VALUE_ID)) { + colorMapParameters.setNoDataValue(((Number) attrs + .get(VIIRSDataRecord.MISSING_VALUE_ID)) + .doubleValue()); + } + if (unitStr != null) { + try { + dataUnit = UnitFormat.getUCUMInstance().parseObject( + unitStr, new ParsePosition(0)); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (offset != null && offset != 0.0) { + dataUnit = dataUnit.plus(offset); + } + if (scale != null && scale != 0.0) { + dataUnit = dataUnit.times(scale); + } + } + + if (record instanceof ShortDataRecord) { + // Setup Min/Max values + // Static, should be moved from ColorMapParameters into + // GLDataFormat + colorMapParameters.setDataMin(0); + colorMapParameters.setDataMax(0xFFFF); + } + } catch (Exception e) { + throw new VizException(e); + } + + colorMapParameters.setDataUnit(dataUnit); + colorMapParameters.setDisplayUnit(displayUnit); + + colorMapParameters.setColorMapMin(colorMapParameters.getDataMin()); + colorMapParameters.setColorMapMax(colorMapParameters.getDataMax()); + if (preferences != null) { + DataScale scale = preferences.getDataScale(); + if (scale != null) { + UnitConverter displayToData = colorMapParameters + .getDisplayToDataConverter(); + if (scale.getMinValue() != null) { + colorMapParameters.setColorMapMin((float) displayToData + .convert(scale.getMinValue())); + } + if (scale.getMaxValue() != null) { + colorMapParameters.setColorMapMax((float) displayToData + .convert(scale.getMaxValue())); + } + if (scale.getMinValue2() != null) { + colorMapParameters.setDataMin((float) displayToData + .convert(scale.getMinValue2())); + } + if (scale.getMaxValue2() != null) { + colorMapParameters.setDataMax((float) displayToData + .convert(scale.getMaxValue2())); + } + } + } + + if (preferences != null && preferences.getColorbarLabeling() != null) { + LabelingPreferences lPrefs = preferences.getColorbarLabeling(); + colorMapParameters.setColorBarIntervals(lPrefs.getValues()); + } + + if (colorMapParameters.getPersisted() != null) { + colorMapParameters.applyPersistedParameters(colorMapParameters + .getPersisted()); + } + + getCapability(ColorMapCapability.class).setColorMapParameters( + colorMapParameters); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#remove(com.raytheon. + * uf.common.time.DataTime) + */ + @Override + public void remove(DataTime dataTime) { + super.remove(dataTime); + synchronized (dataRecordMap) { + Iterator> iter = dataRecordMap + .entrySet().iterator(); + while (iter.hasNext()) { + Entry entry = iter.next(); + VIIRSDataRecord record = entry.getKey(); + if (VIIRSResourceData.withinRange(dataTime.getValidPeriod(), + record.getDataTime())) { + iter.remove(); + RecordData data = entry.getValue(); + data.tileSet.dispose(); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#disposeInternal() + */ + @Override + protected void disposeInternal() { + synchronized (dataRecordMap) { + for (RecordData data : dataRecordMap.values()) { + data.tileSet.dispose(); + } + dataRecordMap.clear(); + dataTimes.clear(); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#paintInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + protected void paintInternal(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + Collection images = getImages(target, paintProps); + if (images.size() > 0) { + if (!target.drawRasters(paintProps, + images.toArray(new DrawableImage[images.size()]))) { + issueRefresh(); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#initInternal(com.raytheon + * .uf.viz.core.IGraphicsTarget) + */ + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + getCapability(ImagingCapability.class).setProvider(this); + synchronized (dataRecordMap) { + resourceChanged(ChangeType.DATA_UPDATE, dataRecordMap.keySet() + .toArray(new PluginDataObject[dataRecordMap.size()])); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.IResourceDataChanged#resourceChanged(com + * .raytheon.uf.viz.core.rsc.IResourceDataChanged.ChangeType, + * java.lang.Object) + */ + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.DATA_UPDATE) { + PluginDataObject[] pdos = (PluginDataObject[]) object; + VIIRSDataRecord[] records = new VIIRSDataRecord[pdos.length]; + for (int i = 0; i < pdos.length; ++i) { + records[i] = (VIIRSDataRecord) pdos[i]; + } + synchronized (dataRecordMap) { + long t0 = System.currentTimeMillis(); + for (VIIRSDataRecord record : records) { + try { + addRecord(record); + } catch (VizException e) { + statusHandler.handle( + Priority.PROBLEM, + "Error adding record from update: " + + e.getLocalizedMessage(), e); + + } + } + System.out.println("Time to add " + records.length + + " records: " + (System.currentTimeMillis() - t0) + + "ms"); + dataTimes = new ArrayList(resourceData + .groupRecordTimes(dataRecordMap.keySet()).keySet()); + } + } + issueRefresh(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#inspect(com.raytheon + * .uf.common.geospatial.ReferencedCoordinate) + */ + @Override + public String inspect(ReferencedCoordinate coord) throws VizException { + Map interMap = interrogate(coord); + double value = Double.NaN; + Number dataVal = (Number) interMap.get(DATA_KEY); + if (dataVal != null) { + value = dataVal.doubleValue(); + } + if (Double.isNaN(value)) { + return "NO DATA"; + } else { + String inspectStr = NUMBER_FORMAT.format(value); + Unit unit = (Unit) interMap.get(UNIT_KEY); + if (unit != null && unit != Unit.ONE) { + inspectStr += " " + UnitFormat.getUCUMInstance().format(unit); + } + return inspectStr; + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#interrogate(com.raytheon + * .uf.common.geospatial.ReferencedCoordinate) + */ + @Override + public Map interrogate(ReferencedCoordinate coord) + throws VizException { + Map interMap = new HashMap(); + ColorMapParameters params = getCapability(ColorMapCapability.class) + .getColorMapParameters(); + interMap.put(UNIT_KEY, params.getDisplayUnit()); + double noDataValue = params.getNoDataValue(); + Coordinate latLon = null; + try { + latLon = coord.asLatLon(); + } catch (Exception e) { + throw new VizException( + "Could not get lat/lon from ReferencedCoordinate", e); + } + DataTime currTime = descriptor.getTimeForResource(this); + if (currTime != null) { + double bestValue = Double.NaN; + // Since there is overlap between granules, the best value is the + // one that is closest to 0 + synchronized (dataRecordMap) { + for (VIIRSDataRecord record : dataRecordMap.keySet()) { + if (VIIRSResourceData.withinRange( + currTime.getValidPeriod(), record.getDataTime())) { + RecordData data = dataRecordMap.get(record); + if (data.intersects && data.project == false) { + double value = data.tileSet.interrogate(latLon); + if (Double.isNaN(value) == false + && value != noDataValue) { + bestValue = value; + break; + } + } + } + } + } + interMap.put(DATA_KEY, + params.getDataToDisplayConverter().convert(bestValue)); + } + return interMap; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#project(org.opengis. + * referencing.crs.CoordinateReferenceSystem) + */ + @Override + public void project(CoordinateReferenceSystem crs) throws VizException { + synchronized (dataRecordMap) { + try { + for (VIIRSDataRecord record : dataRecordMap.keySet()) { + RecordData data = dataRecordMap.get(record); + data.intersects = intersects(record); + data.project = true; + } + } catch (Exception e) { + statusHandler.handle(Priority.PROBLEM, + "Error reprojecting VIIRS data", e); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.drawables.ext.IImagingExtension.ImageProvider + * #getImages(com.raytheon.uf.viz.core.IGraphicsTarget, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + @Override + public Collection getImages(IGraphicsTarget target, + PaintProperties paintProps) throws VizException { + List images = new ArrayList(); + DataTime currTime = paintProps.getDataTime(); + if (currTime != null) { + TimeRange tr = currTime.getValidPeriod(); + synchronized (dataRecordMap) { + for (VIIRSDataRecord record : dataRecordMap.keySet()) { + if (VIIRSResourceData.withinRange(tr, record.getDataTime())) { + RecordData data = dataRecordMap.get(record); + if (data.intersects) { + if (data.project) { + data.tileSet.project(descriptor + .getGridGeometry()); + data.project = false; + } + images.addAll(data.tileSet.getImagesToRender( + target, paintProps)); + } + } + } + } + } + return images; + } +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSResourceData.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSResourceData.java new file mode 100644 index 0000000000..6ab2837909 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/rsc/VIIRSResourceData.java @@ -0,0 +1,294 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.rsc; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; + +import com.raytheon.uf.common.dataplugin.PluginDataObject; +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint; +import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; +import com.raytheon.uf.common.time.DataTime; +import com.raytheon.uf.common.time.TimeRange; +import com.raytheon.uf.viz.core.catalog.LayerProperty; +import com.raytheon.uf.viz.core.datastructure.DataCubeContainer; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; +import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.LoadProperties; + +/** + * VIIRS Resource data + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Nov 30, 2011            mschenke     Initial creation
+ * Feb 21, 2012 #30        mschenke     Switched time query to use dataTime.refTime 
+ *                                      since stored dataTimes now contain a time range
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +public class VIIRSResourceData extends AbstractRequestableResourceData { + + private static class DataTimeIterator + implements Iterator { + + private Iterator pdoIter; + + private T lastAccesed; + + private DataTimeIterator(Iterator pdoIter) { + this.pdoIter = pdoIter; + } + + @Override + public boolean hasNext() { + return pdoIter.hasNext(); + } + + @Override + public DataTime next() { + lastAccesed = pdoIter.next(); + return lastAccesed.getDataTime(); + } + + @Override + public void remove() { + pdoIter.remove(); + } + } + + @XmlElement + private int groupTimeRangeMinutes = 3; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData# + * constructResource(com.raytheon.uf.viz.core.rsc.LoadProperties, + * com.raytheon.uf.viz.core.rsc.PluginDataObject[]) + */ + @Override + protected AbstractVizResource constructResource( + LoadProperties loadProperties, PluginDataObject[] objects) + throws VizException { + List viirsRecords = new ArrayList(); + for (PluginDataObject pdo : objects) { + if (pdo instanceof VIIRSDataRecord) { + viirsRecords.add((VIIRSDataRecord) pdo); + } + } + return new VIIRSResource(this, loadProperties, viirsRecords); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData# + * requestPluginDataObjects(java.util.Collection) + */ + @Override + protected PluginDataObject[] requestPluginDataObjects( + Collection loadSet) throws VizException { + List timesToLoad = new ArrayList(loadSet); + Collections.sort(timesToLoad); + DataTime first = timesToLoad.get(0); + DataTime last = timesToLoad.get(timesToLoad.size() - 1); + Map requestMap = new HashMap( + getMetadataMap()); + RequestConstraint timeConst = new RequestConstraint(); + timeConst.setConstraintType(ConstraintType.BETWEEN); + timeConst.setBetweenValueList(new String[] { + new DataTime(first.getValidPeriod().getStart()).toString(), + new DataTime(last.getValidPeriod().getEnd()).toString() }); + requestMap.put("dataTime.refTime", timeConst); + + LayerProperty property = new LayerProperty(); + property.setEntryQueryParameters(requestMap, false); + property.setNumberOfImages(9999); + + List pdos = DataCubeContainer.getData(property, 60000); + List finalList = new ArrayList( + pdos != null ? pdos.size() : 0); + + if (pdos != null) { + for (Object obj : pdos) { + PluginDataObject pdo = (PluginDataObject) obj; + for (DataTime dt : loadSet) { + if (withinRange(dt.getValidPeriod(), pdo.getDataTime())) { + finalList.add(pdo); + break; + } + } + } + Collections.sort(finalList, layerComparator); + } + return finalList.toArray(new PluginDataObject[finalList.size()]); + } + + public static boolean withinRange(TimeRange range, DataTime time) { + long refTime = time.getMatchRef(); + return range.getStart().getTime() <= refTime + && range.getEnd().getTime() >= refTime; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData# + * getAvailableTimes() + */ + @Override + public DataTime[] getAvailableTimes() throws VizException { + Collection dts = groupTimes(Arrays.asList(super + .getAvailableTimes())); + return dts.toArray(new DataTime[dts.size()]); + } + + /** + * Group times for a {@link PluginDataObject} collection based on + * {@link #groupTimeRangeMinutes} + * + * @param records + * @return + */ + public Map> groupRecordTimes( + Collection records) { + long groupTimeInMillis = groupTimeRangeMinutes * 60 * 1000; + Map> grouped = new HashMap>(); + Queue objects = new ArrayDeque(records); + while (objects.size() > 0) { + T record = objects.remove(); + DataTime current = record.getDataTime(); + TimeRange prev, curr; + prev = curr = current.getValidPeriod(); + + List group = new ArrayList(); + while (curr != null) { + prev = curr; + DataTimeIterator iter = new DataTimeIterator( + objects.iterator()); + curr = match(iter, current.getValidPeriod(), groupTimeInMillis); + if (curr != null) { + group.add(iter.lastAccesed); + } + } + + grouped.put(new DataTime(prev.getStart().getTime(), prev), group); + } + return grouped; + } + + /** + * Group the {@link DataTime} collection based on + * {@link #groupTimeRangeMinutes} + * + * @param dataTimes + * @return + */ + public Collection groupTimes(Collection dataTimes) { + long groupTimeInMillis = groupTimeRangeMinutes * 60 * 1000; + List grouped = new ArrayList(dataTimes.size()); + Queue objects = new ArrayDeque(dataTimes); + while (objects.size() > 0) { + DataTime current = objects.remove(); + TimeRange prev, curr; + prev = curr = current.getValidPeriod(); + while (curr != null) { + prev = curr; + curr = match(objects.iterator(), current.getValidPeriod(), + groupTimeInMillis); + } + + grouped.add(new DataTime(prev.getStart().getTime(), prev)); + } + return grouped; + } + + private TimeRange match(Iterator iter, TimeRange time, + long groupTimeInMillis) { + long startT = time.getStart().getTime(); + long endT = time.getEnd().getTime(); + while (iter.hasNext()) { + DataTime dt = iter.next(); + TimeRange dtRange = dt.getValidPeriod(); + long s = dtRange.getStart().getTime(); + long e = dtRange.getEnd().getTime(); + long startCheck = s - groupTimeInMillis; + long endCheck = e + groupTimeInMillis; + if ((startT <= startCheck && endT >= startCheck) + || (startCheck <= startT && endCheck >= startT)) { + iter.remove(); + return new TimeRange(Math.min(s, startT), Math.max(e, endT)); + } + } + return null; + } + + /** + * @return the groupTimeRangeMinutes + */ + public int getGroupTimeRangeMinutes() { + return groupTimeRangeMinutes; + } + + /** + * @param groupTimeRangeMinutes + * the groupTimeRangeMinutes to set + */ + public void setGroupTimeRangeMinutes(int groupTimeRangeMinutes) { + this.groupTimeRangeMinutes = groupTimeRangeMinutes; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData#update(java + * .lang.Object) + */ + @Override + public void update(Object updateData) { + super.update(updateData); + invalidateAvailableTimesCache(); + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/style/VIIRSDataMatchCriteria.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/style/VIIRSDataMatchCriteria.java new file mode 100644 index 0000000000..4e2707e1c6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/style/VIIRSDataMatchCriteria.java @@ -0,0 +1,157 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.style; + +import java.util.Arrays; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.raytheon.uf.viz.core.style.MatchCriteria; +import com.raytheon.uf.viz.core.style.VizStyleException; + +/** + * Style match criteria for VIIRS data, order of importance is parameter, + * wavelength, channelType, region + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Dec 7, 2011            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "viirsDataMatches") +public class VIIRSDataMatchCriteria extends MatchCriteria { + + @XmlElement + private String parameter; + + @XmlElement + private Double[] wavelength; + + @XmlElement + private String channelType; + + @XmlElement + private String region; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.core.style.MatchCriteria#matches(com.raytheon + * .uf. viz.core.style.MatchCriteria) + */ + @Override + public int matches(MatchCriteria aCriteria) throws VizStyleException { + int rval = -1; + if (aCriteria instanceof VIIRSDataRecordCriteria) { + return VIIRSDataRecordCriteria.matches( + (VIIRSDataRecordCriteria) aCriteria, this); + } else if (aCriteria instanceof VIIRSDataMatchCriteria) { + rval = 0; + VIIRSDataMatchCriteria criteria = (VIIRSDataMatchCriteria) aCriteria; + if (region != null && region.equals(criteria.region)) { + rval |= (1 << 0); + } + if (channelType != null && channelType.equals(criteria.channelType)) { + rval |= (1 << 1); + } + if (wavelength != null && criteria.wavelength != null + && Arrays.equals(wavelength, criteria.wavelength)) { + rval |= (1 << 2); + } + if (parameter != null && parameter.equals(criteria.parameter)) { + rval |= (1 << 3); + } + } + return rval; + } + + /** + * @return the parameter + */ + public String getParameter() { + return parameter; + } + + /** + * @param parameter + * the parameter to set + */ + public void setParameter(String parameter) { + this.parameter = parameter; + } + + /** + * @return the wavelength + */ + public Double[] getWavelength() { + return wavelength; + } + + /** + * @param wavelength + * the wavelength to set + */ + public void setWavelength(Double[] wavelength) { + this.wavelength = wavelength; + } + + /** + * @return the channelType + */ + public String getChannelType() { + return channelType; + } + + /** + * @param channelType + * the channelType to set + */ + public void setChannelType(String channelType) { + this.channelType = channelType; + } + + /** + * @return the region + */ + public String getRegion() { + return region; + } + + /** + * @param region + * the region to set + */ + public void setRegion(String region) { + this.region = region; + } + +} diff --git a/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/style/VIIRSDataRecordCriteria.java b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/style/VIIRSDataRecordCriteria.java new file mode 100644 index 0000000000..277867e761 --- /dev/null +++ b/cave/com.raytheon.uf.viz.npp.viirs/src/com/raytheon/uf/viz/npp/viirs/style/VIIRSDataRecordCriteria.java @@ -0,0 +1,142 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.npp.viirs.style; + +import com.raytheon.uf.common.dataplugin.npp.viirs.VIIRSDataRecord; +import com.raytheon.uf.viz.core.style.MatchCriteria; +import com.raytheon.uf.viz.core.style.VizStyleException; + +/** + * Match criteria for a populated {@link VIIRSDataRecord} object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class VIIRSDataRecordCriteria extends MatchCriteria { + + private final String parameter; + + private final Double wavelength; + + private final String channelType; + + private final String region; + + public VIIRSDataRecordCriteria(VIIRSDataRecord record) { + this.parameter = record.getParameter(); + this.wavelength = record.getWavelength(); + this.channelType = record.getChannelType(); + this.region = record.getRegion(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.style.MatchCriteria#matches(com.raytheon.uf. + * viz.core.style.MatchCriteria) + */ + @Override + public int matches(MatchCriteria aCriteria) throws VizStyleException { + int rval = -1; + if (aCriteria instanceof VIIRSDataMatchCriteria) { + return matches(this, (VIIRSDataMatchCriteria) aCriteria); + } else if (aCriteria instanceof VIIRSDataRecordCriteria) { + rval = 0; + VIIRSDataRecordCriteria criteria = (VIIRSDataRecordCriteria) aCriteria; + if (region != null && region.equals(criteria.region)) { + rval |= (1 << 0); + } + if (channelType != null && channelType.equals(criteria.channelType)) { + rval |= (1 << 1); + } + if (wavelength != null && wavelength.equals(criteria.wavelength)) { + rval |= (1 << 2); + } + if (parameter != null && parameter.equals(criteria.parameter)) { + rval |= (1 << 3); + } + } + return rval; + } + + /** + * Matches a data record criteria to a viirs style rule criteria. Weight + * from least to most goes: region, channelType, wavelength, parameter + * + * @param recordCriteria + * @param matchCriteria + * @return + */ + public static int matches(VIIRSDataRecordCriteria recordCriteria, + VIIRSDataMatchCriteria matchCriteria) { + int rval = 0; + // Check region + if (matchCriteria.getRegion() != null + && matchCriteria.getRegion().equals(recordCriteria.region)) { + rval |= (1 << 0); + } else if (matchCriteria.getRegion() != null) { + --rval; + } + // Check channelType + if (matchCriteria.getChannelType() != null + && matchCriteria.getChannelType().equals( + recordCriteria.channelType)) { + rval |= (1 << 1); + } else if (matchCriteria.getChannelType() != null) { + --rval; + } + // Check wavelength + if (matchCriteria.getWavelength() != null) { + boolean matches = false; + for (Double wavelength : matchCriteria.getWavelength()) { + if (wavelength.equals(recordCriteria.wavelength)) { + matches = true; + break; + } + } + if (matches) { + rval |= (1 << 2); + } else { + --rval; + } + } + // Check parameter + if (matchCriteria.getParameter() != null + && matchCriteria.getParameter() + .equals(recordCriteria.parameter)) { + rval |= (1 << 3); + } else if (matchCriteria.getParameter() != null) { + --rval; + } + return rval; + } +} diff --git a/cave/com.raytheon.uf.viz.points/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.points/META-INF/MANIFEST.MF index c1e3270c8e..0843cff542 100644 --- a/cave/com.raytheon.uf.viz.points/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.points/META-INF/MANIFEST.MF @@ -13,7 +13,14 @@ Require-Bundle: org.eclipse.ui, com.raytheon.uf.viz.core;bundle-version="1.12.1174", com.raytheon.uf.common.time;bundle-version="1.12.1174", com.raytheon.viz.core;bundle-version="1.12.1174", - com.raytheon.uf.common.awipstools;bundle-version="1.12.1174" + com.raytheon.uf.common.awipstools;bundle-version="1.12.1174", + com.raytheon.viz.ui;bundle-version="1.12.1174", + com.raytheon.uf.viz.core.rsc;bundle-version="1.0.0", + com.raytheon.viz.ui.tools.map;bundle-version="1.12.1174" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy -Export-Package: com.raytheon.uf.viz.points +Export-Package: com.raytheon.uf.viz.points, + com.raytheon.uf.viz.points.data, + com.raytheon.uf.viz.points.ui.action, + com.raytheon.uf.viz.points.ui.dialog, + com.raytheon.uf.viz.points.ui.layer diff --git a/cave/com.raytheon.uf.viz.points/build.properties b/cave/com.raytheon.uf.viz.points/build.properties index 34d2e4d2da..c6baffa001 100644 --- a/cave/com.raytheon.uf.viz.points/build.properties +++ b/cave/com.raytheon.uf.viz.points/build.properties @@ -1,4 +1,5 @@ source.. = src/ output.. = bin/ bin.includes = META-INF/,\ - . + .,\ + icons/ diff --git a/cave/com.raytheon.uf.viz.points/icons/group.gif b/cave/com.raytheon.uf.viz.points/icons/group.gif new file mode 100644 index 0000000000..4575eb1a90 Binary files /dev/null and b/cave/com.raytheon.uf.viz.points/icons/group.gif differ diff --git a/cave/com.raytheon.uf.viz.points/icons/point.gif b/cave/com.raytheon.uf.viz.points/icons/point.gif new file mode 100644 index 0000000000..4949431e63 Binary files /dev/null and b/cave/com.raytheon.uf.viz.points/icons/point.gif differ diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointRequest.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointRequest.java new file mode 100644 index 0000000000..205b511ec8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointRequest.java @@ -0,0 +1,91 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points; + +import com.raytheon.uf.viz.points.data.GroupNode; +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; + +/** + * This class is used to queue actions to perform on a Point's localization + * file. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 23, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointRequest { + public static enum RequestType { + ADD, UPDATE, DELETE + }; + + private final RequestType type; + + private final IPointNode point; + + /** + * The constructor. + * + * @param type + * - Kind of request to perform + * @param point + * - The point to pefrom the request on. + */ + public PointRequest(RequestType type, IPointNode point) { + this.type = type; + // Duplicate the point to capture information as it exists at the time + // of the request. + if (point.isGroup()) { + this.point = new GroupNode((Point) point); + } else { + this.point = new Point((Point) point); + } + } + + public IPointNode getPoint() { + return point; + } + + public RequestType getType() { + return type; + } + + public String toString() { + StringBuilder sb = new StringBuilder("PointUpdatedMessage - "); + sb.append("type: ").append(type).append(", point: "); + if (point == null) { + sb.append("null\n"); + } else { + sb.append("\"").append(point.getName()).append("\", \"") + .append(point.getGroup()).append("\"\n"); + } + return sb.toString(); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointUtilities.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointUtilities.java new file mode 100644 index 0000000000..a0cd257668 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointUtilities.java @@ -0,0 +1,112 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Several static utility methods and constants for use on points. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 16, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointUtilities { + public static final char DELIM_CHAR = '~'; + + public static final String DELIMITER = String.valueOf(DELIM_CHAR); + + public static final int MAX_LATITUDE = 90; + + public static final int MAX_LONGITUDE = 180; + + public static final double MINUTE_PER_DEGREE = 60; + + public static final double SECOND_PER_MINUTE = 60; + + private static final Pattern RedundantWhiteSpace = Pattern.compile("\\s+"); + + private static final Pattern SingleSpace = Pattern.compile("\\s"); + + private static final Pattern invalidFileName = Pattern + .compile("[^A-Za-z0-9_ ]"); + + private PointUtilities() { + // Never need an instance of this class. + } + + public static String removeRedundantWhiteSpace(String name) { + Matcher matcher = RedundantWhiteSpace.matcher(name); + String str = matcher.replaceAll(" "); + return str; + } + + /** + * Replaces whitespace in name with delimiter. + * + * @param name + * @return str + */ + public static String convertSpaceToDelimiter(String name) { + Matcher matcher = SingleSpace.matcher(name); + String str = matcher.replaceAll(DELIMITER); + return str; + } + + /** + * Trim leading and trailing whitespace and remove redundant inner + * whitespace. + * + * @param str + * @return + */ + public static String trimAll(String str) { + str = str.trim(); + str = PointUtilities.removeRedundantWhiteSpace(str); + return str; + } + + /** + * This method defines a valid file name as any alpha-numeric name and + * containing only underscores and spaces. + * + * @param filename + * @return + */ + public static boolean isValidFileName(String filename) { + boolean isValid = true; + Matcher matcher = invalidFileName.matcher(filename); + if (matcher.find()) { + isValid = false; + } + return isValid; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointsDataManager.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointsDataManager.java index bb7936a588..e254caa7a1 100644 --- a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointsDataManager.java +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/PointsDataManager.java @@ -19,30 +19,38 @@ **/ package com.raytheon.uf.viz.points; -import java.io.BufferedReader; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import javax.measure.converter.UnitConverter; import javax.measure.unit.NonSI; import javax.measure.unit.SI; +import javax.xml.bind.JAXB; +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; -import org.eclipse.jface.util.IPropertyChangeListener; -import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.graphics.RGB; import org.geotools.referencing.GeodeticCalculator; import org.geotools.referencing.datum.DefaultEllipsoid; import com.raytheon.uf.common.awipstools.GetWfoCenterPoint; import com.raytheon.uf.common.localization.FileUpdatedMessage; +import com.raytheon.uf.common.localization.FileUpdatedMessage.FileChangeType; import com.raytheon.uf.common.localization.ILocalizationFileObserver; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; @@ -51,18 +59,25 @@ import com.raytheon.uf.common.localization.LocalizationContext.LocalizationType; import com.raytheon.uf.common.localization.LocalizationFile; import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.core.localization.LocalizationManager; import com.raytheon.uf.viz.core.requests.ThriftClient; -import com.raytheon.viz.core.CorePlugin; +import com.raytheon.uf.viz.points.PointRequest.RequestType; +import com.raytheon.uf.viz.points.data.GroupNode; +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointFieldState; +import com.raytheon.uf.viz.points.data.PointNameChangeException; import com.vividsolutions.jts.geom.Coordinate; /** * This manages maintaining localized files that contain information on points - * including the special point home. + * including the special point home. The home is also managed in localization + * preferences, however the two should match. * *
  * 
@@ -78,8 +93,7 @@ import com.vividsolutions.jts.geom.Coordinate;
  * @version 1.0
  */
 
-public class PointsDataManager implements ILocalizationFileObserver,
-        IPropertyChangeListener {
+public class PointsDataManager implements ILocalizationFileObserver {
     private static final transient IUFStatusHandler statusHandler = UFStatus
             .getHandler(PointsDataManager.class);
 
@@ -91,28 +105,63 @@ public class PointsDataManager implements ILocalizationFileObserver,
 
     private static PointsDataManager theManager;
 
-    private static final String MOVABLE_POINT_PREFIX = "movablePoint";
-
-    private static final String MOVABLE_POINT_EXT = ".txt";
-
     private static final String HOME_LOCATION_FILE = "HomeLocation.dat";
 
-    private Map points;
+    private static final String GROUP_INFO = "group.dat";
+
+    private static final String GROUP_TEMP_PREFIX = "TEMP_";
+
+    private static final String D2D_POINTS_GROUP = "D2D Points";
+
+    private static final String POINT_FILENAME_PREFIX = "map-point-";
+
+    private static final String POINT_FILENAME_EXT = ".txt";
+
+    private static final String POINTS_DIR = "points";
+
+    private static final String ROOT_NODE_KEY = "";
+
+    private static final String AWIPSTOOLS = "awipsTools";
 
     private ListenerList pointsListeners = new ListenerList();
 
+    private final Map points = new HashMap();
+
     private Coordinate home;
 
-    private ListenerList homeListeners = new ListenerList();
+    private final ListenerList homeListeners = new ListenerList();
 
     private Coordinate wfoCenter;
 
     private String site;
 
-    private LocalizationFile userToolsDir;
+    private final LocalizationContext userCtx;
+
+    private final LocalizationFile userToolsDir;
+
+    private final LocalizationFile pointsDir;
 
     private IPathManager pathMgr;
 
+    private LinkedList requestList;
+
+    private final Map> childrenKeyMap;
+
+    /**
+     * Prior to deleting a group's directory we must get the acknowledgment that
+     * all its children have been deleted otherwise the delete of the directory
+     * may fail. The key is the directory name to delete and the list is the
+     * files in the directory that we need to get acknowledgment they have been
+     * deleted.
+     */
+    private final Map> groupDeleteMap;
+
+    /**
+     * Job to handle performing changes to the Localization files to maintain
+     * points and groups.
+     */
+    private Job processRequestJob;
+
     public static synchronized PointsDataManager getInstance() {
         if (theManager == null) {
             theManager = new PointsDataManager();
@@ -120,23 +169,90 @@ public class PointsDataManager implements ILocalizationFileObserver,
         return theManager;
     }
 
+    /**
+     * Private constructor to maintain singleton instance.
+     */
     private PointsDataManager() {
         site = LocalizationManager.getInstance().getCurrentSite();
 
         pathMgr = PathManagerFactory.getPathManager();
-        LocalizationContext userCtx = pathMgr.getContext(
-                LocalizationType.CAVE_STATIC, LocalizationLevel.USER);
+        userCtx = pathMgr.getContext(LocalizationType.CAVE_STATIC,
+                LocalizationLevel.USER);
 
-        userToolsDir = pathMgr.getLocalizationFile(userCtx, "awipsTools"
+        pointsDir = pathMgr.getLocalizationFile(userCtx, AWIPSTOOLS
+                + File.separator + site + File.separator + POINTS_DIR);
+        userToolsDir = pathMgr.getLocalizationFile(userCtx, AWIPSTOOLS
                 + File.separator + site);
         userToolsDir.addFileUpdatedObserver(this);
 
-        CorePlugin.getDefault().getPreferenceStore()
-                .addPropertyChangeListener(this);
+        childrenKeyMap = new HashMap>();
+
+        groupDeleteMap = new HashMap>();
+
+        requestList = new LinkedList();
+
     }
 
-    public Collection getPointNames() {
-        return getPoints().keySet();
+    /**
+     * Queue a request to be perform latter by processRequests.
+     * 
+     * @param request
+     */
+    private void queueRequest(PointRequest request) {
+        synchronized (requestList) {
+            requestList.add(request);
+        }
+    }
+
+    /**
+     * This starts a job to process the request queue.
+     */
+    private void processRequests() {
+        firePointChangeListeners();
+
+        if (processRequestJob == null) {
+            processRequestJob = new Job("Point Requests") {
+
+                @Override
+                protected IStatus run(IProgressMonitor monitor) {
+                    PointRequest request = null;
+                    while (true) {
+                        synchronized (requestList) {
+                            if (requestList.isEmpty()) {
+                                processRequestJob = null;
+                                break;
+                            }
+                            request = requestList.remove();
+                        }
+
+                        Point point = (Point) request.getPoint();
+                        switch (request.getType()) {
+                        case ADD:
+                            if (!point.isGroup()) {
+                                storePoint(point);
+                            } else {
+                                Point parent = points.get(getParentKey(point));
+                                String parentPath = getPointDirName(parent);
+                                createGroup(parentPath, point.getName());
+                            }
+                            break;
+                        case UPDATE:
+                            Assert.isTrue(!point.isGroup());
+                            storePoint(point);
+                            break;
+                        case DELETE:
+                            removePoint(point);
+                            break;
+                        default:
+                            statusHandler.handle(Priority.ERROR,
+                                    "Unknown PointChangeType");
+                        }
+                    }
+                    return Status.OK_STATUS;
+                }
+            };
+            processRequestJob.schedule();
+        }
     }
 
     /**
@@ -145,21 +261,37 @@ public class PointsDataManager implements ILocalizationFileObserver,
      * @return the point coordinate associated with the given name, null if no
      *         point exists by that name
      */
-    public Coordinate getPoint(String name) {
-        if (points == null) {
-            getPoints();
-        }
-        Coordinate pointCoordinate = points.get(name);
-        if (pointCoordinate == null) {
+    public Coordinate getCoordinate(String name) {
+        Point point = getPointsMap().get(name);
+        if (point == null) {
             return null;
         }
-        return new Coordinate(pointCoordinate);
+        return point.getCoordinate();
     }
 
-    public void setPoint(String name, Coordinate point) {
-        points.put(name, new Coordinate(point));
-        storePoint(userToolsDir, point, MOVABLE_POINT_PREFIX + name
-                + MOVABLE_POINT_EXT);
+    /**
+     * Obtain the point for the given name.
+     * 
+     * @param name
+     * @return point
+     */
+    public Point getPoint(String name) {
+        return getPointsMap().get(name);
+    }
+
+    /**
+     * Change the coordinate for the point associated with the name.
+     * 
+     * @param name
+     * @param coordinate
+     */
+    public void setCoordinate(String name, Coordinate coordinate) {
+        Point point = getPointsMap().get(name);
+        Assert.isNotNull(point, "Point not found for " + name);
+        point.setCoordinate(coordinate);
+        PointRequest request = new PointRequest(RequestType.UPDATE, point);
+        queueRequest(request);
+        processRequests();
     }
 
     /**
@@ -174,6 +306,11 @@ public class PointsDataManager implements ILocalizationFileObserver,
         return new Coordinate(wfoCenter);
     }
 
+    /**
+     * Obtain the home point's coordinate.
+     * 
+     * @return coordinate.
+     */
     public Coordinate getHome() {
         if (home == null) {
             loadHome();
@@ -181,6 +318,11 @@ public class PointsDataManager implements ILocalizationFileObserver,
         return new Coordinate(home);
     }
 
+    /**
+     * Update and save the home point's new coordinate.
+     * 
+     * @param home
+     */
     public void setHome(Coordinate home) {
         if (home == null) {
             return;
@@ -189,70 +331,180 @@ public class PointsDataManager implements ILocalizationFileObserver,
         storeHome();
     }
 
-    private void storeHome() {
-        storePoint(userToolsDir, home, HOME_LOCATION_FILE);
-    }
-
-    private void storePoint(LocalizationFile dir, Coordinate point,
-            String fileName) {
-
-        LocalizationFile lf = pathMgr.getLocalizationFile(dir.getContext(),
-                dir.getName() + File.separator + fileName);
-        File file = lf.getFile();
-
-        // create the local directory if necessary
-        if (!file.getParentFile().exists()) {
-            file.getParentFile().mkdirs();
-        }
-
-        BufferedWriter out = null;
-        try {
-            out = new BufferedWriter(new FileWriter(file));
-            out.write(String.format("%f %f\n", point.y, point.x));
-        } catch (IOException e) {
-            statusHandler.handle(Priority.PROBLEM, "Error writing to file: "
-                    + file.getAbsolutePath(), e);
-        } finally {
-            if (out != null) {
-                try {
-                    out.close();
-                    lf.save();
-                } catch (IOException e) {
-                    statusHandler.handle(Priority.PROBLEM,
-                            "Error writing to file: " + file.getAbsolutePath(),
-                            e);
-                } catch (LocalizationException e) {
-                    statusHandler.handle(Priority.PROBLEM,
-                            "Error storing locatization file to server: " + lf,
-                            e);
-                }
+    /**
+     * Obtain a list of all points that are visible.
+     * 
+     * @return visiblePoints
+     */
+    public Collection getVisiblePointNames() {
+        Collection visiblePoints = new ArrayList();
+        for (String name : getPointsMap().keySet()) {
+            Point point = points.get(name);
+            if (!point.isGroup() && point.getHidden() == PointFieldState.FALSE) {
+                visiblePoints.add(name);
             }
         }
+        return visiblePoints;
     }
 
-    private Map getPoints() {
-        if (points == null || points.isEmpty()) {
-            loadPoints();
-            if (points == null || points.isEmpty()) {
+    /**
+     * Get a list of all point names (no groups).
+     * 
+     * @return pointNames
+     */
+    public Collection getPointNames() {
+        Collection pointNames = new ArrayList();
+        for (String key : getPointsMap().keySet()) {
+            if (!points.get(key).isGroup()) {
+                pointNames.add(key);
+            }
+        }
+        return pointNames;
+    }
+
+    /**
+     * Store home coordinates in the root directory; fires an
+     * ILocalizationFileObserver event
+     */
+    private void storeHome() {
+        Point point = new Point("", home.y, home.x, PointFieldState.FALSE,
+                PointFieldState.FALSE, false, new RGB(0, 0, 0), ROOT_NODE_KEY);
+        storePoint(pointsDir, point, HOME_LOCATION_FILE);
+    }
+
+    /**
+     * Add a new Point file to the persistent store; fires an
+     * ILocalizationFileObserver event
+     * 
+     * @param dir
+     * @param point
+     */
+    private void storePoint(LocalizationFile dir, Point point) {
+
+        String fileName = getPointFileName(point.getName());
+        storePoint(dir, point, fileName);
+    }
+
+    /**
+     * @param dir
+     * @param point
+     * @param fileName
+     */
+    private void storePoint(LocalizationFile dir, Point point, String fileName) {
+        LocalizationFile lFile = pathMgr.getLocalizationFile(userCtx, dir
+                .getName().trim() + File.separator + fileName);
+
+        try {
+            marshalPointToXmlFile(point, lFile);
+        } catch (Exception e) {
+            statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
+        }
+    }
+
+    /**
+     * Given a Point original name (e.g. Brooklyn Bridge), return the
+     * conventional file name (e.g.map-point-Brooklyn~Bridge.txt)
+     * 
+     * @param name
+     * @return
+     */
+    private String getPointFileName(String name) {
+        name = PointUtilities.convertSpaceToDelimiter(name);
+        String fileName = POINT_FILENAME_PREFIX + name + POINT_FILENAME_EXT;
+        return fileName;
+    }
+
+    /**
+     * Get all points including groups.
+     * 
+     * @return
+     */
+    public Collection getPoints() {
+        return getPointsMap().values();
+    }
+
+    /**
+     * This checks and if needed loads points. It will also check and create the
+     * default points and the group they belong to.
+     * 
+     * @return points
+     */
+    private Map getPointsMap() {
+        boolean doRequest = false;
+        if (points.isEmpty()) {
+            doRequest = loadPoints();
+            String d2dKey = File.separator + D2D_POINTS_GROUP;
+            Point d2dPoint = points.get(d2dKey);
+            if (d2dPoint != null) {
+                if (childrenKeyMap.get(d2dKey).size() == 0) {
+                    createDefaultPoints();
+                    processRequests();
+                }
+            } else {
+                String dirPath = pointsDir.getName().trim();
+                String name = D2D_POINTS_GROUP.replace(' ',
+                        PointUtilities.DELIM_CHAR);
+                String path = dirPath + File.separator + name;
+                LocalizationFile d2dDir = pathMgr.getLocalizationFile(userCtx,
+                        path);
+                if (!d2dDir.isDirectory()) {
+                    try {
+                        d2dDir.delete();
+                    } catch (LocalizationOpFailedException e) {
+                        statusHandler.handle(Priority.PROBLEM,
+                                "Unable to create group: " + D2D_POINTS_GROUP);
+                        return points;
+                    }
+                }
+                d2dPoint = new GroupNode();
+                d2dPoint.setName(D2D_POINTS_GROUP);
+                d2dPoint.setGroup(d2dKey);
+                PointRequest request = new PointRequest(RequestType.ADD,
+                        d2dPoint);
+                queueRequest(request);
+                String parentKey = ROOT_NODE_KEY;
+                childrenKeyMap.get(parentKey).add(d2dKey);
+                childrenKeyMap.put(d2dKey, new ArrayList());
+                put(d2dKey, d2dPoint);
                 createDefaultPoints();
+                doRequest = true;
+            }
+
+            if (doRequest) {
+                processRequests();
             }
         }
         return points;
     }
 
+    /**
+     * This creates D2D Point group and the default A-J points for the group.
+     */
     private void createDefaultPoints() {
-        points = new HashMap();
         Coordinate center = getHome();
         int baseRingSize = 120;
         int startAngle = -90;
+        String group = File.separator + D2D_POINTS_GROUP;
+        List d2dChildren = childrenKeyMap.get(group);
         for (char label = 'A'; label <= 'J'; label++) {
-            Coordinate point = getCoordinateOnCircle(center, baseRingSize,
+            String name = String.valueOf(label);
+
+            Coordinate coordinate = getCoordinateOnCircle(center, baseRingSize,
                     startAngle);
-            setPoint(String.valueOf(label), point);
+            Point point = new Point(name, coordinate.y, coordinate.x,
+                    PointFieldState.FALSE, PointFieldState.TRUE, false,
+                    new RGB(0, 0, 0), group);
+            PointRequest request = new PointRequest(RequestType.ADD, point);
+            queueRequest(request);
+            put(name, point);
+            d2dChildren.add(name);
             startAngle += 36;
         }
     }
 
+    /**
+     * Set wfoCenter to the sites center point.
+     */
     private void loadWfoCenter() {
         try {
             // Request WFO center point from server
@@ -267,32 +519,588 @@ public class PointsDataManager implements ILocalizationFileObserver,
         }
     }
 
+    /**
+     * Loads home point from the localize file and returns its coordinate.
+     * 
+     * @return home
+     */
     private Coordinate loadHome() {
-        home = loadPoint(userToolsDir, HOME_LOCATION_FILE);
-        if (home == null) {
+        LocalizationFile lFile = pathMgr.getLocalizationFile(
+                pointsDir.getContext(), pointsDir.getName().trim()
+                        + File.separator + HOME_LOCATION_FILE);
+        Point point = null;
+        if (lFile.exists()) {
+            point = loadPoint(lFile);
+        }
+
+        if (point == null) {
             home = getWfoCenter();
             storeHome();
+        } else {
+            home = point.getCoordinate();
         }
         return home;
     }
 
-    private void loadPoints() {
-        points = new HashMap();
+    /**
+     * Clear mapping of points and children and create all points and group
+     * nodes from the localization files and directory structure.
+     */
+    private boolean loadPoints() {
+        boolean doRequest = false;
+        points.clear();
+        childrenKeyMap.clear();
 
-        LocalizationFile[] files = pathMgr.listFiles(userToolsDir.getContext(),
-                userToolsDir.getName(), new String[] { MOVABLE_POINT_EXT },
-                false, true);
-        for (LocalizationFile lf : files) {
-            String fileName = lf.getFile().getName();
-            if (fileName.startsWith(MOVABLE_POINT_PREFIX)) {
-                Coordinate point = loadPoint(userToolsDir, fileName);
-                String name = fileName.substring(MOVABLE_POINT_PREFIX.length())
-                        .replace(MOVABLE_POINT_EXT, "");
-                points.put(name, point);
+        String path = pointsDir.getName().trim();
+        LocalizationFile[] files = pathMgr.listFiles(userCtx, path,
+                new String[] { POINT_FILENAME_EXT }, true, false);
+
+        if (files.length == 0) {
+            pointsDir.getFile().mkdirs();
+            Point point = new GroupNode(ROOT_NODE_KEY);
+            String key = point.getGroup();
+            PointRequest request = new PointRequest(RequestType.ADD, point);
+            queueRequest(request);
+            put(key, point);
+            childrenKeyMap.put(key, new ArrayList());
+            doRequest = true;
+        } else {
+            Point point = null;
+            for (LocalizationFile lf : files) {
+                point = loadPoint(lf);
+                String key = getPointKey(lf);
+                put(key, point);
+                if (point.isGroup()) {
+                    childrenKeyMap.put(key, new ArrayList());
+                }
+                if (key.length() > 0) {
+                    // p
+                    String parentKey = getParentKey(point);
+                    childrenKeyMap.get(parentKey).add(key);
+                }
             }
         }
+        doNodeState(points.get(ROOT_NODE_KEY));
+        return doRequest;
+    }
+
+    private void doNodeState(IPointNode node) {
+
+        // Make sure all the children are in proper state.
+        for (IPointNode child : getChildren(node, true)) {
+            if (child.isGroup()) {
+                doNodeState(child);
+            }
+        }
+
+        // The children list now have the proper state.
+        List children = getChildren(node, true);
+        if (children.size() == 0) {
+            ((Point) node).setHidden(PointFieldState.FALSE);
+            ((Point) node).setMovable(PointFieldState.TRUE);
+            put(getPointKey((Point) node), (Point) node);
+            return;
+        }
+
+        IPointNode child = children.remove(0);
+        PointFieldState hidden = child.getHidden();
+        PointFieldState movable = child.getMovable();
+        int unknownCnt = 0;
+
+        if (hidden == PointFieldState.UNKNOWN) {
+            ++unknownCnt;
+        }
+
+        if (movable == PointFieldState.UNKNOWN) {
+            ++unknownCnt;
+        }
+
+        while (children.size() > 0 && unknownCnt < 2) {
+            child = children.remove(0);
+            if (hidden != PointFieldState.UNKNOWN
+                    && hidden != child.getHidden()) {
+                hidden = PointFieldState.UNKNOWN;
+                ++unknownCnt;
+            }
+            if (movable != PointFieldState.UNKNOWN
+                    && movable != child.getMovable()) {
+                movable = PointFieldState.UNKNOWN;
+                ++unknownCnt;
+            }
+        }
+        ((Point) node).setHidden(hidden);
+        ((Point) node).setMovable(movable);
+        put(getPointKey((Point) node), (Point) node);
+    }
+
+    /**
+     * Parse a localization file and return the point it contains; does NOT fire
+     * an ILocalizationFileObserver event.
+     * 
+     * @param lFile
+     * @return point
+     */
+    private Point loadPoint(LocalizationFile lFile) {
+        Point point = null;
+
+        if (lFile.isDirectory()) {
+            String key = getPointKey(lFile);
+            point = points.get(key);
+            if (point == null) {
+                point = new GroupNode(getPointName(lFile));
+                point.setGroup(key);
+            }
+            return point;
+        }
+
+        try {
+            point = unmarshalPointFromXmlFile(lFile);
+        } catch (IOException ex) {
+            StringBuffer sb = new StringBuffer(lFile.toString());
+            sb.replace(0, pointsDir.toString().length(), "");
+            int index = sb.lastIndexOf(File.separator);
+            sb.setLength(index);
+            point.setGroup(sb.toString());
+
+            statusHandler.handle(Priority.PROBLEM,
+                    "Unable to open localized file: " + lFile, ex);
+        } catch (LocalizationException e) {
+            statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
+        }
+
+        if (point != null) {
+            StringBuffer sb = new StringBuffer(lFile.toString());
+            sb.replace(0, pointsDir.toString().length(), "");
+            int index = sb.lastIndexOf(File.separator);
+            sb.setLength(index);
+            point.setGroup(sb.toString());
+        }
+        return point;
+    }
+
+    /**
+     * Get the point's group localized file.
+     * 
+     * @param point
+     * @return lFile
+     */
+    private LocalizationFile getGroupDir(Point point) {
+        String path = (pointsDir.getName() + point.getGroup().replace(' ',
+                PointUtilities.DELIM_CHAR));
+        LocalizationFile dir = pathMgr.getLocalizationFile(userCtx, path);
+        return dir;
+    }
+
+    /**
+     * Get the points and non-empty group nodes that are the children of the
+     * node.
+     * 
+     * @param node
+     * @return children
+     */
+    public List getChildren(IPointNode node) {
+        return getChildren(node, false);
+    }
+
+    /**
+     * Get children of node. When node is null the children of the root node are
+     * returned.
+     * 
+     * @param node
+     * @param allGroups
+     *            - When true include all groups otherwise only non-empty groups
+     *            are included.
+     * @return children
+     */
+    public List getChildren(IPointNode node, boolean allGroups) {
+        // Make sure point maps are are loaded.
+        getPointsMap();
+
+        String parentKey = null;
+        if (node == null) {
+            parentKey = ROOT_NODE_KEY;
+        } else {
+            parentKey = getPointKey((Point) node);
+        }
+
+        List childrenKeyList = childrenKeyMap.get(parentKey);
+        List children = new ArrayList();
+        if (childrenKeyList != null) {
+            if (allGroups) {
+                for (String key : childrenKeyList) {
+                    children.add(points.get(key));
+                }
+            } else {
+                for (String key : childrenKeyList) {
+                    IPointNode child = points.get(key);
+                    if (!child.isGroup()
+                            || childrenKeyMap.get(getPointKey((Point) child))
+                                    .size() > 0) {
+                        children.add(child);
+                    }
+                }
+            }
+            sort(children);
+        }
+        return children;
+    }
+
+    /**
+     * Sort the collection of nodes placing group before points.
+     * 
+     * @param nodes
+     */
+    private void sort(List nodes) {
+        Collections.sort(nodes, new Comparator() {
+
+            @Override
+            public int compare(IPointNode o1, IPointNode o2) {
+                return o1.compareTo(o2);
+            }
+        });
+    }
+
+    /**
+     * Get the localization file name for the point.
+     * 
+     * @param point
+     * @return filename
+     */
+    private String getPointFilename(Point point) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(pointsDir.getName().trim());
+        String group = point.getGroup();
+        if (!group.startsWith(File.separator)) {
+            sb.append(File.separator);
+        }
+        sb.append(point.getGroup()).append(File.separator)
+                .append(POINT_FILENAME_PREFIX).append(point.getName())
+                .append(POINT_FILENAME_EXT);
+        String filename = sb.toString().replace(' ', PointUtilities.DELIM_CHAR);
+        return filename;
+    }
+
+    /**
+     * Get the localization path for the group node.
+     * 
+     * @param node
+     * @return path
+     */
+    private String getPointDirName(Point node) {
+        String group = node.getGroup();
+        StringBuilder sb = new StringBuilder();
+        sb.append(pointsDir.getName().trim());
+        if (group.length() > 0) {
+            if (group.charAt(0) != File.separatorChar) {
+                sb.append(File.separator);
+            }
+            sb.append(group);
+        }
+        String path = sb.toString().replace(' ', PointUtilities.DELIM_CHAR);
+        return path;
+    }
+
+    /**
+     * Get the name for the point/node for the localization file.
+     * 
+     * @param lFile
+     * @return name
+     */
+    private String getPointName(LocalizationFile lFile) {
+        String name = null;
+        StringBuilder sb = new StringBuilder();
+        sb.append(lFile.toString());
+        sb.replace(0, sb.lastIndexOf(File.separator) + 1, "");
+        if (!lFile.isDirectory()) {
+            sb.replace(0, POINT_FILENAME_PREFIX.length(), "");
+            sb.replace(sb.length() - POINT_FILENAME_EXT.length(), sb.length(),
+                    "");
+        }
+        name = sb.toString().replace(PointUtilities.DELIM_CHAR, ' ');
+        return name;
+    }
+
+    /**
+     * Obtain the unique key for the point represented by the localization file.
+     * 
+     * @param lFile
+     * @return key
+     */
+    private String getPointKey(LocalizationFile lFile) {
+        String key = null;
+        if (!lFile.isDirectory()) {
+            key = getPointName(lFile);
+        } else {
+            StringBuilder sb = new StringBuilder();
+            sb.append(lFile.toString());
+            sb.replace(0, pointsDir.toString().length(), "");
+            key = sb.toString();
+        }
+        return key.replace(PointUtilities.DELIM_CHAR, ' ');
+    }
+
+    /**
+     * Determine the key for the point.
+     * 
+     * @param point
+     * @return key
+     */
+    private String getPointKey(Point point) {
+        String key = null;
+        if (!point.isGroup()) {
+            key = point.getName();
+        } else {
+            key = point.getGroup();
+        }
+        return key;
+    }
+
+    /**
+     * Get the key for the parent of the point.
+     * 
+     * @param point
+     * @return parentKey
+     */
+    private String getParentKey(Point point) {
+        String parentKey = point.getGroup();
+        if (point.isGroup() && parentKey.length() > 0) {
+            parentKey = parentKey.substring(0,
+                    parentKey.lastIndexOf(File.separator));
+        }
+        return parentKey;
+    }
+
+    /**
+     * @param node
+     * @return
+     */
+    public IPointNode getParent(IPointNode node) {
+        Point parent = points.get(getParentKey((Point) node));
+        return new GroupNode(parent);
+    }
+
+    /**
+     * This generates a temporary name for new group node under the desired
+     * parent. This can serves as a place holder in a dialog's tree structure;
+     * allowing a user to type in the new name for the group or keep the
+     * temporary name.
+     * 
+     * @param parentNode
+     * @return groupNode
+     * @throws LocalizationOpFailedException
+     */
+    public IPointNode createTempGroup(IPointNode parentNode)
+            throws LocalizationOpFailedException {
+        Point parent = (Point) parentNode;
+        String path = getPointDirName(parent);
+        StringBuilder sb = new StringBuilder(path);
+
+        LocalizationFile[] dirs = pathMgr.listStaticFiles(sb.toString(),
+                new String[0], false, false);
+        sb.append(File.separator).append(GROUP_TEMP_PREFIX);
+        int end = sb.length();
+
+        List names = new ArrayList();
+        for (LocalizationFile lf : dirs) {
+            names.add(lf.getName().trim());
+        }
+
+        int cnt = 0;
+        while (true) {
+            sb.setLength(end);
+            sb.append(++cnt);
+            if (!names.contains(sb.toString())) {
+                break;
+            }
+        }
+        String name = GROUP_TEMP_PREFIX + cnt;
+        Point node = new GroupNode();
+        node.setName(name);
+        String parentKey = getPointKey(parent);
+        node.setGroup(parentKey + File.separator + name);
+        String nodeKey = getPointKey(node);
+        PointRequest request = new PointRequest(RequestType.ADD, node);
+        queueRequest(request);
+        childrenKeyMap.get(parentKey).add(nodeKey);
+        put(nodeKey, node);
+        childrenKeyMap.put(nodeKey, new ArrayList());
+        processRequests();
+        return node;
+    }
+
+    /**
+     * Moves a node to the new location.
+     * 
+     * @param node
+     * @param destNode
+     */
+    public void moveNode(final IPointNode node, final IPointNode destNode) {
+        String oldParentKey = getParentKey((Point) node);
+        String destKey = getPointKey((Point) destNode);
+        if (oldParentKey.equals(destKey)) {
+            return;
+        }
+        doMoveNode(node, destNode);
+        checkGroupState(points.get(oldParentKey));
+        checkGroupState(destNode);
+        processRequests();
+    }
+
+    /**
+     * Recursive method to handle moving a group node.
+     * 
+     * @param node
+     * @param destNode
+     */
+    private void doMoveNode(IPointNode node, IPointNode destNode) {
+        String key = getPointKey((Point) node);
+        Point point = points.get(key);
+        String newParentKey = getPointKey((Point) destNode);
+        if (!point.isGroup()) {
+            doDeletePoint(point);
+            point.setGroup(newParentKey);
+            doAddPoint(point);
+            put(key, point);
+            childrenKeyMap.get(newParentKey).add(key);
+        } else {
+            Point newGroup = new GroupNode((Point) point);
+            String newGroupKey = newParentKey + File.separator
+                    + point.getName();
+            newGroup.setGroup(newGroupKey);
+            PointRequest request = new PointRequest(RequestType.ADD, newGroup);
+            queueRequest(request);
+            put(newGroupKey, newGroup);
+            childrenKeyMap.put(newGroupKey, new ArrayList());
+            childrenKeyMap.get(newParentKey).add(newGroupKey);
+
+            for (IPointNode child : getChildren(node)) {
+                doMoveNode(child, newGroup);
+            }
+            doDeletePoint(point);
+        }
     }
 
+    /**
+     * Renames a group node and handles moving its childern to the new
+     * localtion.
+     * 
+     * @param srcNode
+     * @param destName
+     * @return
+     */
+    public boolean renameGroup(final IPointNode srcNode, final String destName) {
+        if (srcNode.getName().equals(destName)) {
+            return false;
+        }
+
+        String parentKey = getParentKey((Point) srcNode);
+        Point parent = points.get(parentKey);
+        Point destNode = new GroupNode(parent);
+        String destKey = parentKey + File.separator + destName;
+        destNode.setName(destName);
+        destNode.setGroup(destKey);
+        PointRequest request = new PointRequest(RequestType.ADD, destNode);
+        queueRequest(request);
+        put(destKey, destNode);
+        childrenKeyMap.get(parentKey).add(destKey);
+        childrenKeyMap.put(destKey, new ArrayList());
+        for (IPointNode child : getChildren(srcNode)) {
+            doMoveNode(child, destNode);
+        }
+        doDeletePoint((Point) srcNode);
+        processRequests();
+        return true;
+    }
+
+    /**
+     * Create a new group
+     * 
+     * @param parent
+     *            group to add new group to
+     * @param name
+     *            of the new group.
+     * @return node The new group or null if group already exists.
+     */
+    private IPointNode createGroup(String parent, String name) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(parent);
+        sb.replace(0, pointsDir.getName().trim().length(), "");
+        sb.append(File.separator).append(name);
+        Point gPoint = new GroupNode(name);
+        gPoint.setGroup(sb.toString().replace(PointUtilities.DELIM_CHAR, ' '));
+        String groupPath = getPointDirName(gPoint);
+        LocalizationFile lFile = pathMgr
+                .getLocalizationFile(userCtx, groupPath);
+
+        // lFile.exits() can return true even when directory doesn't exist.
+        // Get a list of the parent's sub-directories and see if group's
+        // directory is in it.
+        LocalizationFile[] files = pathMgr.listFiles(userCtx, parent,
+                new String[] {}, false, false);
+        for (LocalizationFile lf : files) {
+            if (groupPath.equals(lf.getName().trim())) {
+                return null;
+            }
+        }
+
+        try {
+            // Must create a file in the directory to force its creation.
+            String p = lFile.getName().trim() + File.separator + GROUP_INFO;
+            LocalizationFile lf = pathMgr.getLocalizationFile(userCtx, p);
+            OutputStream outStream = lf.openOutputStream();
+            outStream.write(gPoint.getGroup().getBytes());
+            outStream.close();
+            lf.save();
+        } catch (LocalizationException e) {
+            statusHandler.handle(Priority.PROBLEM,
+                    "Unable to create the group: " + gPoint.getGroup(), e);
+            return null;
+        } catch (IOException e) {
+            statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
+        }
+        return new GroupNode(gPoint);
+    }
+
+    /**
+     * Determine if a point exits for the given name.
+     * 
+     * @param name
+     * @return true when point exits otherwise false
+     */
+    public boolean exists(String name) {
+        return getPointNames().contains(name);
+    }
+
+    /**
+     * Obtains a sorted list of groups
+     * 
+     * @return groups
+     */
+    public String[] getGroupList() {
+        LocalizationFile[] files = pathMgr.listFiles(userCtx, pointsDir
+                .getName().trim(), new String[] {}, true, false);
+        String[] groups = new String[files.length - 1];
+        int start = files[0].getName().trim().length();
+        for (int index = 1; index < files.length; ++index) {
+            LocalizationFile lf = files[index];
+            groups[index - 1] = lf.getName().trim().substring(start)
+                    .replace(PointUtilities.DELIM_CHAR, ' ');
+        }
+        Arrays.sort(groups);
+        return groups;
+    }
+
+    /**
+     * Determine the coordinate of point on a circle.
+     * 
+     * @param coor
+     *            - center of the circle
+     * @param radius
+     *            - Distance to the point
+     * @param angle
+     *            - Angle from the center
+     * @return coordinate
+     */
     public Coordinate getCoordinateOnCircle(Coordinate coor, double radius,
             int angle) {
 
@@ -318,26 +1126,260 @@ public class PointsDataManager implements ILocalizationFileObserver,
     public void fileUpdated(FileUpdatedMessage message) {
         String fileName = new File(message.getFileName()).getName();
 
-        if (fileName.startsWith(MOVABLE_POINT_PREFIX)) {
-            pointsFileUpdated(fileName);
-        } else if (fileName.startsWith(HOME_LOCATION_FILE)) {
+        if (fileName.startsWith(HOME_LOCATION_FILE)) {
             homeLocationFileUpdated(fileName);
+            return;
+        }
+
+        // Assume message is for a directory (group), GROUP_INFO or point map
+        // file. If the changes are already in this instance of class then the
+        // message can be ignored. Otherwise we need to update this instance and
+        // notify listeners.
+        boolean stateChange = false;
+        if (fileName.startsWith(POINT_FILENAME_PREFIX)
+                && fileName.endsWith(POINT_FILENAME_EXT)) {
+            stateChange = checkPoint(message, fileName);
+        } else if (fileName.equals(GROUP_INFO)) {
+            stateChange = checkGroup(message);
+        } else if (message.getChangeType() == FileChangeType.DELETED) {
+            // Assume group directory that may be on the pending delete list.
+            checkGroupDelete(message);
+        }
+
+        if (stateChange) {
+            firePointChangeListeners();
         }
     }
 
-    private void pointsFileUpdated(String fileName) {
-        if (points != null) {
-            Coordinate point = loadPoint(userToolsDir, fileName);
-            String name = fileName.substring(MOVABLE_POINT_PREFIX.length())
-                    .replace(MOVABLE_POINT_EXT, "");
-            points.put(name, point);
+    /**
+     * Determine if the message needs to be acted upon by this instance of CAVE.
+     * 
+     * @param message
+     * @param fileName
+     * @return
+     */
+    private boolean checkPoint(FileUpdatedMessage message, String fileName) {
+        boolean stateChange = false;
 
-            for (Object listener : pointsListeners.getListeners()) {
-                ((IPointChangedListener) listener).pointChanged();
+        StringBuilder sb = new StringBuilder(message.getFileName());
+        sb.replace(0, pointsDir.getName().length(), "");
+        sb.replace(sb.lastIndexOf(File.separator), sb.length(), "");
+        String groupKey = sb.toString().replace(PointUtilities.DELIM_CHAR, ' ');
+
+        sb.setLength(0);
+        sb.append(fileName);
+        sb.replace(0, POINT_FILENAME_PREFIX.length(), "");
+        sb.replace(sb.length() - POINT_FILENAME_EXT.length(), sb.length(), "");
+        String key = sb.toString().replace(PointUtilities.DELIM_CHAR, ' ');
+
+        Point foundPoint = points.get(key);
+        Point point = null;
+        LocalizationFile lFile = null;
+        switch (message.getChangeType()) {
+        case ADDED:
+            lFile = pathMgr.getLocalizationFile(userCtx, message.getFileName());
+            point = loadPoint(lFile);
+            if (foundPoint == null) {
+                put(key, point);
+                childrenKeyMap.get(groupKey).add(key);
+                checkGroupState(getParent(point));
+                stateChange = true;
+            } else if (!groupKey.equals(foundPoint.getGroup())) {
+                // Finishing up moving the point to a different group.
+                childrenKeyMap.get(foundPoint.getGroup()).remove(key);
+                childrenKeyMap.get(groupKey).add(key);
+                put(key, point);
+                checkGroupState(getParent(point));
+                stateChange = true;
+            }
+            break;
+        case UPDATED:
+            lFile = pathMgr.getLocalizationFile(userCtx, message.getFileName());
+            point = loadPoint(lFile);
+            if (foundPoint == null) {
+                statusHandler.handle(Priority.PROBLEM,
+                        "Unable to find point to update: " + key);
+            } else if (!groupKey.equals(foundPoint.getGroup())) {
+                statusHandler.handle(Priority.PROBLEM,
+                        "Updated point in wrong group: " + key);
+            } else if (point.differentContent(foundPoint)) {
+                put(key, point);
+                checkGroupState(getParent(point));
+                stateChange = true;
+            }
+            break;
+        case DELETED:
+            if (foundPoint != null) {
+                // When groups are different assume in the middle of move
+                // (delete/add) do nothing and let the ADDED handle it.
+                if (groupKey.equals(foundPoint.getGroup())) {
+                    IPointNode parent = getParent(foundPoint);
+                    childrenKeyMap.get(groupKey).remove(key);
+                    remove(key);
+                    checkGroupState(parent);
+                    stateChange = true;
+                }
+            } else {
+                checkGroupDelete(message);
+            }
+            break;
+        default:
+            statusHandler.handle(Priority.DEBUG, "Unhandled change type: "
+                    + message.getChangeType());
+        }
+        return stateChange;
+    }
+
+    /**
+     * Check to see if the node's movable and hidden state and if changed check
+     * its parent node.
+     * 
+     * @param node
+     *            - group node to check
+     * @return true - when either movable or hidden have changed otherwise false
+     */
+    private boolean checkGroupState(IPointNode node) {
+        List children = getChildren(node, true);
+        if (children.size() == 0) {
+            return false;
+        }
+
+        IPointNode child = children.remove(0);
+        PointFieldState hidden = child.getHidden();
+        PointFieldState movable = child.getMovable();
+
+        int unknownCnt = 0;
+        if (hidden == PointFieldState.UNKNOWN) {
+            ++unknownCnt;
+        }
+
+        if (movable == PointFieldState.UNKNOWN) {
+            ++unknownCnt;
+        }
+
+        while (children.size() > 0 && unknownCnt < 2) {
+            child = children.remove(0);
+            if (hidden != PointFieldState.UNKNOWN
+                    && hidden != child.getHidden()) {
+                hidden = PointFieldState.UNKNOWN;
+                ++unknownCnt;
+            }
+            if (movable != PointFieldState.UNKNOWN
+                    && movable != child.getMovable()) {
+                movable = PointFieldState.UNKNOWN;
+                ++unknownCnt;
+            }
+        }
+        boolean value = false;
+        if (hidden != node.getHidden()) {
+            value = true;
+        }
+        if (movable != node.getMovable()) {
+            value = true;
+        }
+
+        if (value) {
+            Point point = points.get(getPointKey((Point) node));
+            point.setHidden(hidden);
+            point.setMovable(movable);
+            if (!getParent(node).equals(ROOT_NODE_KEY)) {
+                checkGroupState(getParent(node));
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Determine if this group message needs to be acted upoin by this instance
+     * of CAVE.
+     * 
+     * @param message
+     * @return
+     */
+    private boolean checkGroup(FileUpdatedMessage message) {
+        boolean stateChange = false;
+        StringBuilder sb = new StringBuilder(message.getFileName());
+        sb.setLength(sb.lastIndexOf(File.separator));
+        sb.replace(0, pointsDir.getName().length(), "");
+        String key = sb.toString().replace(PointUtilities.DELIM_CHAR, ' ');
+        String parentKey = null;
+        int index = key.lastIndexOf(File.separator);
+        if (index >= 0) {
+            parentKey = key.substring(0, index);
+        }
+        Point foundGroup = points.get(key);
+
+        switch (message.getChangeType()) {
+        case ADDED:
+            if (foundGroup == null) {
+                sb.replace(0, sb.lastIndexOf(File.separator) + 1, "");
+                String name = sb.toString().replace(PointUtilities.DELIM_CHAR,
+                        ' ');
+                Point point = new GroupNode();
+                point.setName(name);
+                point.setGroup(key);
+                put(key, point);
+                childrenKeyMap.get(parentKey).add(key);
+                childrenKeyMap.put(key, new ArrayList());
+                checkGroupState(getParent(point));
+                stateChange = true;
+            }
+            break;
+        case DELETED:
+            if (foundGroup != null) {
+                if (childrenKeyMap.get(key).size() > 0) {
+                    statusHandler.handle(Priority.PROBLEM, "Removing group \""
+                            + key + "\" while it contains points or groups");
+                }
+                childrenKeyMap.remove(key);
+                childrenKeyMap.get(parentKey).remove(key);
+                remove(key);
+                checkGroupState(points.get(parentKey));
+                stateChange = true;
+            } else {
+                checkGroupDelete(message);
+            }
+            break;
+        default:
+            statusHandler.handle(Priority.DEBUG, "Unexepected change type "
+                    + message.getChangeType() + " for group \"" + key + "\"");
+        }
+        return stateChange;
+    }
+
+    /**
+     * Check the message's file name to see if it needs to be removed from a
+     * pending delete list and see if it is time to delete the parent's
+     * directory.
+     * 
+     * @param message
+     */
+    private void checkGroupDelete(FileUpdatedMessage message) {
+        String filename = message.getFileName();
+        String deleteKey = filename.substring(0,
+                filename.lastIndexOf(File.separator));
+        List childList = groupDeleteMap.get(deleteKey);
+        if (childList != null) {
+            childList.remove(filename);
+            if (childList.size() == 0) {
+                LocalizationFile lFile = pathMgr.getLocalizationFile(userCtx,
+                        deleteKey);
+                try {
+                    lFile.delete();
+                } catch (LocalizationOpFailedException e) {
+                    statusHandler.handle(Priority.PROBLEM,
+                            e.getLocalizedMessage(), e);
+                }
+                groupDeleteMap.remove(deleteKey);
             }
         }
     }
 
+    /**
+     * Let everyone know about the update to the home point.
+     * 
+     * @param fileName
+     */
     private void homeLocationFileUpdated(String fileName) {
         if (home != null) {
             loadHome();
@@ -348,16 +1390,16 @@ public class PointsDataManager implements ILocalizationFileObserver,
                 // fire listeners in separate threads to avoid waiting to draw
                 // the updated location while waiting on another listener to
                 // finish
-                Thread t = new Thread(new Runnable() {
+                Job job = new Job("Home Location Update") {
 
                     @Override
-                    public void run() {
+                    protected IStatus run(IProgressMonitor monitor) {
                         ((IPointChangedListener) listener).pointChanged();
+                        return Status.OK_STATUS;
                     }
 
-                });
-                threads.add(t);
-                t.start();
+                };
+                job.schedule();
             }
 
             // join all threads before continuing so we can't fire listeners
@@ -375,51 +1417,6 @@ public class PointsDataManager implements ILocalizationFileObserver,
         }
     }
 
-    private Coordinate loadPoint(LocalizationFile dir, String fileName) {
-        Coordinate point = null;
-
-        LocalizationFile lf = pathMgr.getLocalizationFile(dir.getContext(),
-                dir.getName() + File.separator + fileName);
-        File file = lf.getFile();
-        BufferedReader in = null;
-        try {
-            in = new BufferedReader(new FileReader(file));
-            String line = in.readLine();
-            line = line.trim();
-            int p = line.indexOf(' ');
-            double lat = Double.parseDouble(line.substring(0, p));
-            double lon = Double.parseDouble(line.substring(p));
-
-            if (lat > 90.0 || lat < -90.0 || lon > 180.0 || lon < -180.0) {
-                statusHandler
-                        .handle(Priority.PROBLEM,
-                                "Invalid lat/lon in wfo center point file, using default");
-            } else {
-                point = new Coordinate(lon, lat);
-            }
-        } catch (NumberFormatException e) {
-            statusHandler
-                    .handle(Priority.PROBLEM,
-                            "Invalid number in wfo center point file, using default",
-                            e);
-        } catch (FileNotFoundException e) {
-            statusHandler.handle(Priority.EVENTA,
-                    "No wfo center point file found, creating default.");
-        } catch (IOException e) {
-            statusHandler.handle(Priority.PROBLEM,
-                    "Error reading wfo center point file, using default", e);
-        } finally {
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e) {
-                    // nothing to do
-                }
-            }
-        }
-        return point;
-    }
-
     /**
      * @param listener
      */
@@ -448,16 +1445,342 @@ public class PointsDataManager implements ILocalizationFileObserver,
         homeListeners.remove(listener);
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange
-     * (org.eclipse.core.runtime.Preferences.PropertyChangeEvent)
+    /**
+     * Let listners no about changes to point or groups.
      */
-    @Override
-    public void propertyChange(PropertyChangeEvent event) {
-        // TODO Auto-generated method stub
+    private void firePointChangeListeners() {
+        for (final Object listener : pointsListeners.getListeners()) {
+            // fire listeners in separate threads to avoid waiting to draw
+            // the updated location while waiting on another listener to
+            // finish
+            Job job = new Job("Point Changed") {
 
+                @Override
+                protected IStatus run(IProgressMonitor monitor) {
+                    ((IPointChangedListener) listener).pointChanged();
+                    return Status.OK_STATUS;
+                }
+
+            };
+            job.schedule();
+        }
+    }
+
+    /**
+     * Add the point (never a group) and create/update its file.
+     * 
+     * @param point
+     */
+    public void addPoint(final Point point) {
+        Assert.isTrue(!point.isGroup());
+
+        String key = getPointKey(point);
+        Point foundPoint = getPointsMap().get(key);
+
+        PointRequest request = null;
+
+        if (foundPoint == null) {
+            request = new PointRequest(RequestType.ADD, point);
+            childrenKeyMap.get(getParentKey(point)).add(key);
+        } else {
+            request = new PointRequest(RequestType.UPDATE, point);
+        }
+        queueRequest(request);
+        put(key, point);
+        checkGroupState(getParent(point));
+        processRequests();
+    }
+
+    /**
+     * Create the quest to add a point and adds it to the queue.
+     * 
+     * @param point
+     */
+    private void doAddPoint(Point point) {
+        PointRequest request = new PointRequest(RequestType.ADD, point);
+        queueRequest(request);
+    }
+
+    /**
+     * The server will return asynchronously via
+     * ILocalizationFileObserver::fileUpdated and a FileUpdatedMessage status of
+     * ADDED if file was successfully created.
+     * 
+     * @param point
+     * @return returns true if point was successfully added, false otherwise,
+     *         for example when a duplicate point name exists and forceOverwrite
+     *         was false
+     */
+    private void storePoint(Point point) {
+        LocalizationFile dir = getGroupDir(point);
+        storePoint(dir, point);
+    }
+
+    /**
+     * Try to delete a Point from the persistent store; the boolean flag just
+     * let's user know of (otherwise impossible?) situation where the Point
+     * somehow disappeared; the server will return asynchronously via
+     * ILocalizationFileObserver::fileUpdated and a FileUpdatedMessage status of
+     * DELETE if file removal is successful.
+     * 
+     * @param point
+     * @return
+     */
+    public void deletePoint(final Point point) {
+        IPointNode parentNode = getParent(point);
+        doDeletePoint(point);
+        checkGroupState(parentNode);
+        processRequests();
+    }
+
+    /**
+     * Queues request to delete a point and if it is a group recursive deletes
+     * its children.
+     * 
+     * @param point
+     */
+    private void doDeletePoint(Point point) {
+        String key = getPointKey(point);
+
+        Point foundPoint = getPoint(key);
+        PointRequest request = null;
+        String pointKey = getPointKey(foundPoint);
+        String parentKey = getParentKey(foundPoint);
+        String deleteKey = getPointDirName(foundPoint);
+
+        if (foundPoint.isGroup()) {
+            // When removing a group node we need to delete the directory
+            // that represents the node. That can not be done until all
+            // entries in the directory are removed. This determines
+            // what we need to have deleted and adds requests to the queue.
+            String groupInfo = deleteKey + File.separator + GROUP_INFO;
+            groupDeleteMap.put(deleteKey, new ArrayList());
+            groupDeleteMap.get(deleteKey).add(groupInfo);
+
+            List children = getChildren(foundPoint, true);
+            for (IPointNode child : children) {
+                doDeletePoint((Point) child);
+            }
+            childrenKeyMap.remove(pointKey);
+        } else {
+            List childList = groupDeleteMap.get(deleteKey);
+            if (childList != null) {
+                childList.add(getPointFilename(foundPoint));
+            }
+        }
+        request = new PointRequest(RequestType.DELETE, foundPoint);
+        queueRequest(request);
+        childrenKeyMap.get(parentKey).remove(pointKey);
+        remove(pointKey);
+    }
+
+    /***
+     * Try to remove a Point file from the persistent store; fires an
+     * ILocalizationFileObserver event.
+     * 
+     * @param point
+     */
+    private void removePoint(Point point) {
+        LocalizationFile lFile = null;
+        if (point.isGroup()) {
+            String name = getPointDirName(point) + File.separator + GROUP_INFO;
+            lFile = pathMgr.getLocalizationFile(userCtx, name);
+        } else {
+            String name = getPointFilename(point);
+            lFile = pathMgr.getLocalizationFile(userCtx, name);
+        }
+        try {
+            if (!lFile.delete()) {
+                statusHandler.error("Unable to remove file: " + lFile);
+            }
+        } catch (LocalizationOpFailedException e1) {
+            statusHandler.handle(Priority.PROBLEM,
+                    "Error deleting locatization file from server: " + lFile);
+        }
+    }
+
+    /**
+     * Updates a point by remove/add if name is changed else by a update
+     * request.
+     * 
+     * @param oldPoint
+     * @param newPoint
+     */
+    public void updatePoint(final Point oldPoint, final Point newPoint) {
+        PointRequest request = null;
+
+        if (!oldPoint.getName().equals(newPoint.getName())
+                || !oldPoint.getGroup().equals(newPoint.getGroup())) {
+            // Points name or group changed need to remove old point and add
+            // new.
+            request = new PointRequest(RequestType.DELETE, oldPoint);
+            queueRequest(request);
+            String oldParentKey = getParentKey(oldPoint);
+            String oldKey = getPointKey(oldPoint);
+            childrenKeyMap.get(oldParentKey).remove(oldKey);
+            request = new PointRequest(RequestType.ADD, newPoint);
+            queueRequest(request);
+            String newParentKey = getParentKey(newPoint);
+            String newKey = getPointKey(newPoint);
+            childrenKeyMap.get(newParentKey).add(newKey);
+            remove(oldKey);
+            put(newKey, newPoint);
+        } else {
+            request = new PointRequest(RequestType.UPDATE, newPoint);
+            queueRequest(request);
+            put(getPointKey(newPoint), newPoint);
+        }
+        checkGroupState(getParent(newPoint));
+        processRequests();
+    }
+
+    /**
+     * Update a non-group point.
+     * 
+     * @param point
+     * @throws PointNameChangeException
+     */
+    public void updatePoint(Point point) throws PointNameChangeException {
+        Assert.isTrue(point != null && !point.isGroup());
+        Point oldPoint = getPoint(point.getName());
+        if (oldPoint == null) {
+            throw new PointNameChangeException("Point does not exist");
+        }
+        addPoint(point);
+    }
+
+    /**
+     * change node's and all it chilren's hidden to the desired state.
+     * 
+     * @param node
+     * @param state
+     */
+    public void updateChildrenHidden(IPointNode node, PointFieldState state) {
+        if (!node.isGroup()) {
+            return;
+        }
+        doChildrenHidden(node, state);
+        checkGroupState(getParent(node));
+        processRequests();
+    }
+
+    /**
+     * Does the recursive work for updateChildrenHidden.
+     * 
+     * @param node
+     * @param state
+     */
+    private void doChildrenHidden(IPointNode node, PointFieldState state) {
+        String key = getPointKey((Point) node);
+        Point point = points.get(key);
+        PointRequest request = null;
+
+        if (!point.isGroup()) {
+            if (point.getHidden() != state) {
+                point.setHidden(state);
+                request = new PointRequest(RequestType.UPDATE, point);
+                queueRequest(request);
+            }
+        } else {
+            point.setHidden(state);
+            List children = getChildren(point);
+            for (IPointNode child : children) {
+                doChildrenHidden(child, state);
+            }
+        }
+    }
+
+    /**
+     * change node's and all it chilren's movable to the desired state.
+     * 
+     * @param node
+     * @param state
+     */
+    public void updateChildrenMovable(IPointNode node, PointFieldState state) {
+        if (!node.isGroup()) {
+            return;
+        }
+        doChildrenMovable(node, state);
+        processRequests();
+    }
+
+    /**
+     * Does the recursive work for updateChildrenMovable.
+     * 
+     * @param node
+     * @param state
+     */
+    private void doChildrenMovable(IPointNode node, PointFieldState state) {
+        String key = getPointKey((Point) node);
+        Point point = points.get(key);
+        PointRequest request = null;
+
+        if (!point.isGroup()) {
+            if (point.getMovable() != state) {
+                point.setMovable(state);
+                request = new PointRequest(RequestType.UPDATE, point);
+                queueRequest(request);
+            }
+        } else {
+            point.setMovable(state);
+            List children = getChildren(point);
+            for (IPointNode child : children) {
+                doChildrenMovable(child, state);
+            }
+        }
+    }
+
+    /**
+     * Use JAXB to convert a point to xml and save it in the localized file.
+     * 
+     * @param point
+     * @param lFile
+     * @throws LocalizationException
+     * @throws IOException
+     */
+    private void marshalPointToXmlFile(Point point, LocalizationFile lFile)
+            throws LocalizationException, IOException {
+        OutputStream stream = lFile.openOutputStream();
+        JAXB.marshal(point, stream);
+        stream.close();
+        lFile.save();
+    }
+
+    /**
+     * Use JAXB to read the xml in the localized file and convert to a point.
+     * 
+     * @param lFile
+     * @return point
+     * @throws LocalizationException
+     * @throws IOException
+     */
+    private Point unmarshalPointFromXmlFile(LocalizationFile lFile)
+            throws LocalizationException, IOException {
+        InputStream stream = lFile.openInputStream();
+        Point point = JAXB.unmarshal(stream, Point.class);
+        stream.close();
+        return point;
+    }
+
+    /**
+     * All put to points should use this in case additional work needs to be
+     * done.
+     * 
+     * @param key
+     * @param point
+     */
+    private void put(String key, Point point) {
+        points.put(key, point);
+    }
+
+    /**
+     * All remove to points should use this in case addtional work needs to be
+     * done.
+     * 
+     * @param key
+     * @return
+     */
+    private Point remove(String key) {
+        return points.remove(key);
     }
 }
diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/GroupNode.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/GroupNode.java
new file mode 100644
index 0000000000..61e4c67c43
--- /dev/null
+++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/GroupNode.java
@@ -0,0 +1,62 @@
+/**
+ * This software was developed and / or modified by Raytheon Company,
+ * pursuant to Contract DG133W-05-CQ-1067 with the US Government.
+ * 
+ * U.S. EXPORT CONTROLLED TECHNICAL DATA
+ * This software product contains export-restricted data whose
+ * export/transfer/disclosure is restricted by U.S. law. Dissemination
+ * to non-U.S. persons whether in the United States or abroad requires
+ * an export license or other authorization.
+ * 
+ * Contractor Name:        Raytheon Company
+ * Contractor Address:     6825 Pine Street, Suite 340
+ *                         Mail Stop B8
+ *                         Omaha, NE 68106
+ *                         402.291.0100
+ * 
+ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
+ * further licensing information.
+ **/
+package com.raytheon.uf.viz.points.data;
+
+import org.eclipse.swt.graphics.RGB;
+
+/**
+ * Sub-class of Point that indicates the node is a group.
+ * 
+ * 
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 16, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class GroupNode extends Point { + public GroupNode() { + super(); + } + + /** + * @param node + */ + public GroupNode(Point node) { + super(node); + } + + public GroupNode(String groupName) { + super(groupName, 0.0, 0.0, PointFieldState.UNKNOWN, + PointFieldState.UNKNOWN, false, new RGB(0, 0, 0), ""); + } + + @Override + public boolean isGroup() { + return true; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/IPointNode.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/IPointNode.java new file mode 100644 index 0000000000..52eef3b4ea --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/IPointNode.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.data; + + +/** + * Interface use to describe a point or group node. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 16, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public interface IPointNode { + public String getName(); + + public String getGroup(); + + public boolean isGroup(); + + public int compareTo(IPointNode target); + + public PointFieldState getHidden(); + + public PointFieldState getMovable(); +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/Point.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/Point.java new file mode 100644 index 0000000000..3592f186e4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/Point.java @@ -0,0 +1,474 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +package com.raytheon.uf.viz.points.data; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.points.PointUtilities; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * A Point is a user-defined, named, geospatial location as defined by a + * latitude and longitude. This also allows the point to be hidden, the point to + * be movable, allow grouping with other points, and finally the font color and + * size to use to display the name on a map. + * + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * October-2010            epolster    Initial Creation.
+ * July 16, 1012 #875      rferrel     Converted for use with CAVE
+ * 
+ * 
+ * 
+ * + * @author epolster + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "point") +@DynamicSerialize +public class Point implements IPointNode, Comparable { + /** + * This is used to compare the double values of latitude and longitude. + */ + private static final double DELTA = 0.000001; + + @XmlElement(name = "name") + @DynamicSerializeElement + private String name; + + @XmlElement(name = "longitude") + @DynamicSerializeElement + private double longitude; + + @XmlElement(name = "latitude") + @DynamicSerializeElement + private double latitude; + + @XmlElement(name = "colorActive") + @DynamicSerializeElement + private boolean colorActive; + + @XmlElement(name = "red") + @DynamicSerializeElement + private int red; + + @XmlElement(name = "green") + @DynamicSerializeElement + private int green; + + @XmlElement(name = "blue") + @DynamicSerializeElement + private int blue; + + @XmlElement(name = "hidden") + @DynamicSerializeElement + private PointFieldState hidden; + + @XmlElement(name = "movable") + @DynamicSerializeElement + private PointFieldState movable; + + @XmlElement(name = "fontSize") + @DynamicSerializeElement + private PointSize fontSize = PointSize.DEFAULT; + + private transient String group; + + public Point() { + this.movable = PointFieldState.TRUE; + this.hidden = PointFieldState.FALSE; + } + + /** + * Copy constructor. + * + * @param point + */ + public Point(Point point) { + this.name = point.name; + this.longitude = point.longitude; + this.latitude = point.latitude; + this.colorActive = point.colorActive; + this.red = point.red; + this.green = point.green; + this.blue = point.blue; + this.fontSize = point.fontSize; + this.hidden = point.hidden; + this.movable = point.movable; + this.group = point.group; + } + + /** + * Constructor must take valid lat/lon coordinates! + * + * @param pointName + * @param lat + * @param lon + * @param hidden + * @param movable + * @param colorActive + * @param c + * @param group + */ + public Point(String pointName, double lat, double lon, + PointFieldState hidden, PointFieldState movable, + boolean colorActive, RGB c, String group) { + setName(pointName); + this.fontSize = PointSize.DEFAULT; + this.colorActive = colorActive; + this.red = c.red; + this.green = c.green; + this.blue = c.blue; + this.movable = movable; + this.hidden = hidden; + this.longitude = lon; + this.latitude = lat; + setGroup(group); + } + + /** + * Constructor must take valid lat/lon coordinates! + * + * @param pointName + * @param lat + * @param lon + * @param movable + * @param colorActive + * @param c + * @param size + * @param group + */ + public Point(String pointName, double lat, double lon, + PointFieldState movable, boolean colorActive, RGB c, + PointSize size, String group) { + setName(pointName); + this.fontSize = size; + this.colorActive = colorActive; + this.red = c.red; + this.green = c.green; + this.blue = c.blue; + this.movable = movable; + this.hidden = PointFieldState.FALSE; + this.longitude = lon; + this.latitude = lat; + setGroup(group); + } + + /** + * @return latitude + */ + public double getLatitude() { + return latitude; + } + + /** + * @param latitude + */ + public void setLatitude(double latitude) { + this.latitude = latitude; + } + + /** + * @return longitude + */ + public double getLongitude() { + return longitude; + } + + /** + * @return coordinate + */ + public Coordinate getCoordinate() { + return new Coordinate(longitude, latitude); + } + + /** + * @param coordinate + */ + public void setCoordinate(Coordinate coordinate) { + this.longitude = coordinate.x; + this.latitude = coordinate.y; + } + + /** + * @param longitude + */ + public void setLongitude(double longitude) { + this.longitude = longitude; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.points.data.IPointNode#getName() + */ + @Override + public String getName() { + return name; + } + + /** + * @param pointName + */ + public void setName(String pointName) { + name = PointUtilities.trimAll(pointName); + } + + /** + * @param state + */ + public void setHidden(PointFieldState state) { + hidden = state; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.points.data.IPointNode#getHidden() + */ + @Override + public PointFieldState getHidden() { + return hidden; + } + + /** + * @return + */ + public boolean isColorActive() { + return colorActive; + } + + /** + * @param colorActive + */ + public void setColorActive(boolean colorActive) { + this.colorActive = colorActive; + } + + /** + * @return rgb + */ + public RGB getColor() { + return new RGB(red, green, blue); + } + + /** + * @param c + */ + public void setColor(RGB c) { + this.red = c.red; + this.green = c.green; + this.blue = c.blue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + public Object clone() { + Point point = new Point(this); + return point; + } + + /** + * @return + */ + public PointSize getFontSize() { + return fontSize; + } + + /** + * @param fs + */ + public void setFontSize(PointSize fs) { + fontSize = fs; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.points.data.IPointNode#getMovable() + */ + @Override + public PointFieldState getMovable() { + return movable; + } + + /** + * @param notAnchored + */ + public void setMovable(PointFieldState notAnchored) { + movable = notAnchored; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.points.data.IPointNode#getGroup() + */ + @Override + public String getGroup() { + return group; + } + + /** + * @param group + */ + public void setGroup(String group) { + this.group = PointUtilities.trimAll(group).replace( + PointUtilities.DELIM_CHAR, ' '); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.points.data.IPointNode#isGroup() + */ + @Override + public boolean isGroup() { + return false; + } + + public int getRed() { + return red; + } + + public void setRed(int red) { + this.red = red; + } + + public int getGreen() { + return green; + } + + public void setGreen(int green) { + this.green = green; + } + + public int getBlue() { + return blue; + } + + public void setBlue(int blue) { + this.blue = blue; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("Point: \n"); + sb.append("\t Name: ").append(name).append("\n"); + sb.append("\t longitude, latitude: ").append("{").append(longitude) + .append(", ").append(latitude).append("}\n"); + sb.append("\t Color Active: ").append(colorActive).append("\n"); + sb.append("\t Color: ").append("(").append(red).append(", ") + .append(green).append(", ").append(blue).append(")") + .append("\n"); + sb.append("\t isHidden: ").append(hidden).append("\n"); + sb.append("\t isMovable: ").append(movable).append("\n"); + sb.append("\t fontSize: ").append(fontSize.toString()).append("\n"); + sb.append("\t group: \"").append(group).append("\"\n"); + sb.append("\t isGroup: ").append(isGroup()).append("\n"); + return sb.toString(); + } + + public Coordinate getLocation() { + return new Coordinate(longitude, latitude); + } + + public void setLocation(Coordinate location) { + this.longitude = location.x; + this.latitude = location.y; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.points.data.IPointNode#compareTo(com.raytheon.uf. + * viz.points.data.IPointNode) + */ + @Override + public int compareTo(IPointNode o) { + // Put groups at the top of a list + if (isGroup()) { + if (!o.isGroup()) { + return -1; + } + } else if (o.isGroup()) { + return 1; + } + return getName().compareToIgnoreCase(o.getName()); + } + + /** + * Determine if any of the contains of point is different. + * + * @param point + * @return state true when contains differ otherwise false + */ + public boolean differentContent(Point point) { + boolean state = false; + if (!name.equals(point.name)) { + state = true; + } else if (Math.abs(latitude - point.latitude) > DELTA) { + state = true; + } else if (Math.abs(longitude - point.longitude) > DELTA) { + state = true; + } else if (colorActive != point.colorActive) { + state = true; + } else if (red != point.red) { + state = true; + } else if (green != point.green) { + state = true; + } else if (blue != point.blue) { + state = true; + } else if (hidden != point.hidden) { + state = true; + } else if (movable != point.movable) { + state = true; + } else if (fontSize != point.fontSize) { + state = true; + } else if (!group.equals(point.group)) { + state = true; + } + return state; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointFieldState.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointFieldState.java new file mode 100644 index 0000000000..714d19f337 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointFieldState.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +package com.raytheon.uf.viz.points.data; + +/** + * The three states for a point's movable and hidden field. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 13, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public enum PointFieldState { + UNKNOWN, TRUE, FALSE +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointNameChangeException.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointNameChangeException.java new file mode 100644 index 0000000000..6f5cd53372 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointNameChangeException.java @@ -0,0 +1,50 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.data; + +/** + * Exception generated by PointsDataManger when there is a problem with + * localization and updating a point. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 16, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointNameChangeException extends Exception { + private static final long serialVersionUID = 1L; + + public PointNameChangeException() { + super(); + } + + public PointNameChangeException(String arg0) { + super(arg0); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointSize.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointSize.java new file mode 100644 index 0000000000..c27965e39d --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointSize.java @@ -0,0 +1,92 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.data; + +/** + * This class for handling point's font sizes. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 08, 2012 #875       rferrel     Initial Creation.
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public enum PointSize { + + SMALL(12), DEFAULT(14), LARGE(18), EXTRA_LARGE(24), XXL(30); + + private static final String POINTS_NAME = " pt"; + + private transient int fontSize; + + private transient String readableName; + + PointSize(int fontSize) { + this.fontSize = fontSize; + this.readableName = " " + fontSize + POINTS_NAME; + } + + public int getFontSize() { + return fontSize; + } + + /** + * @param ordinal + * @return ps + */ + static public PointSize getPointSize(int ordinal) { + PointSize newPS = null; + switch (ordinal) { + case 0: + newPS = SMALL; + break; + case 1: + newPS = DEFAULT; + break; + case 2: + newPS = LARGE; + break; + case 3: + newPS = EXTRA_LARGE; + break; + case 4: + newPS = XXL; + break; + } + return newPS; + } + + /** + * A descriptive name usable in a combo box item. + * + * @return name + */ + public String getReadableName() { + return readableName; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointTransfer.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointTransfer.java new file mode 100644 index 0000000000..13c552eeee --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointTransfer.java @@ -0,0 +1,164 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.data; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.dnd.ByteArrayTransfer; +import org.eclipse.swt.dnd.TransferData; + +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; + +/** + * This singleton class converts an instance of the Point class to a byte array + * or an byte array to an instance of Point. This is used to support drag and + * drop. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 13, 2012 875        rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointTransfer extends ByteArrayTransfer { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(PointTransfer.class); + + private static final String TYPE_NAME = "point_type"; + + private static final int TYPE_ID = registerType(TYPE_NAME); + + private static PointTransfer instance = new PointTransfer(); + + public static PointTransfer getInstance() { + return instance; + } + + private PointTransfer() { + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.ByteArrayTransfer#javaToNative(java.lang.Object, + * org.eclipse.swt.dnd.TransferData) + */ + @Override + protected void javaToNative(Object object, TransferData transferData) { + if (object == null || !(object instanceof Point[])) { + return; + } + + if (isSupportedType(transferData)) { + Point[] points = (Point[]) object; + + ArrayList transfers = new ArrayList(); + for (Point point : points) { + PointTransferObject transfer = new PointTransferObject(); + if (point.isGroup()) { + transfer.setPoint(new Point(point)); + } else { + transfer.setPoint(point); + } + transfer.setGroupNode(point.isGroup()); + transfer.setGroupName(point.getGroup()); + transfers.add(transfer); + } + + try { + byte[] buffer = SerializationUtil.transformToThrift(transfers); + super.javaToNative(buffer, transferData); + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.dnd.ByteArrayTransfer#nativeToJava(org.eclipse.swt.dnd + * .TransferData) + */ + @SuppressWarnings("unchecked") + @Override + protected Object nativeToJava(TransferData transferData) { + Point[] points = null; + if (isSupportedType(transferData)) { + byte[] buffer = (byte[]) super.nativeToJava(transferData); + if (buffer != null) { + try { + List transfers = (List) SerializationUtil + .transformFromThrift(buffer); + points = new Point[transfers.size()]; + int index = 0; + for (PointTransferObject transfer : transfers) { + Point point = transfer.getPoint(); + if (transfer.isGroupNode()) { + point = new GroupNode(point); + } + point.setGroup(transfer.getGroupName()); + points[index] = point; + ++index; + } + } catch (SerializationException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + return points; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.Transfer#getTypeNames() + */ + @Override + protected String[] getTypeNames() { + return new String[] { TYPE_NAME }; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.swt.dnd.Transfer#getTypeIds() + */ + @Override + protected int[] getTypeIds() { + return new int[] { TYPE_ID }; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointTransferObject.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointTransferObject.java new file mode 100644 index 0000000000..ff0f98d83e --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/data/PointTransferObject.java @@ -0,0 +1,81 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.data; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * This object used by PointTransfer to serialize a IPointNode preserving its + * group information. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 20, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +@DynamicSerialize +public class PointTransferObject { + + @DynamicSerializeElement + private Point point; + + @DynamicSerializeElement + private boolean groupNode; + + @DynamicSerializeElement + private String groupName; + + public PointTransferObject() { + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + public boolean isGroupNode() { + return groupNode; + } + + public void setGroupNode(boolean group) { + this.groupNode = group; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/action/PointEditAction.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/action/PointEditAction.java new file mode 100644 index 0000000000..039875cba8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/action/PointEditAction.java @@ -0,0 +1,74 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.action; + +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.points.ui.dialog.PointsMgrDialog; +import com.raytheon.uf.viz.points.ui.layer.PointsToolLayer; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; + +/** + * Aciton class for displaying the points manager dialog. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 27, 2012 875        rferrel     Initial creation
+ * 
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointEditAction extends AbstractRightClickAction { + + private PointsMgrDialog dialog; + + @Override + public boolean isHidden() { + if (getSelectedRsc() instanceof PointsToolLayer) { + return false; + } + return true; + } + + @Override + public String getText() { + return "Edit Points..."; + } + + @Override + public void run() { + if (dialog == null || dialog.getShell() == null || dialog.isDisposed()) { + dialog = new PointsMgrDialog(Display.getCurrent().getShells()[0], + (PointsToolLayer) getSelectedRsc()); + dialog.setBlockOnOpen(false); + dialog.open(); + } else { + dialog.bringToTop(); + } + } +} diff --git a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/PointsToolAction.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/action/PointsToolAction.java similarity index 87% rename from cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/PointsToolAction.java rename to cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/action/PointsToolAction.java index f45ebfdfb5..68793431a7 100644 --- a/cave/com.raytheon.viz.awipstools/src/com/raytheon/viz/awipstools/ui/action/PointsToolAction.java +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/action/PointsToolAction.java @@ -17,10 +17,11 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.viz.awipstools.ui.action; +package com.raytheon.uf.viz.points.ui.action; -import com.raytheon.viz.awipstools.ui.display.AwipsToolsResourceData; -import com.raytheon.viz.awipstools.ui.layer.PointsToolLayer; +import com.raytheon.uf.viz.core.rsc.tools.AwipsToolsResourceData; +import com.raytheon.uf.viz.core.rsc.tools.action.AbstractMapToolAction; +import com.raytheon.uf.viz.points.ui.layer.PointsToolLayer; /** * Handles the Points Tool Action. diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/CoordinateInputPanel.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/CoordinateInputPanel.java new file mode 100644 index 0000000000..ce023d976d --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/CoordinateInputPanel.java @@ -0,0 +1,714 @@ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +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.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.viz.points.PointUtilities; +import com.raytheon.uf.viz.points.data.Point; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * This panel creates the layout and performs the logic for latitude and + * longitude information. + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ *  October-2010              epolster    Initial Creation.
+ *  July 21 2012 875         rferrel     Made sizing dynamic
+ * 
+ * 
+ * + * @author epolster + * @version 1 + * + * + */ + +public class CoordinateInputPanel { + + static private String DEGREES_MINUTES_SECONDS = " Degrees : Minutes : Seconds"; + + static private String DEGREES_MINUTES = " Degrees : Minutes"; + + static private String DEGREES_ONLY = " Degrees Only"; + + private Text latDegreesText; + + private Text latMinutesText; + + private Text latSecondsText; + + private Text lonDegreesText; + + private Text lonMinutesText; + + private Text lonSecondsText; + + private Button cardinalNorthRadioButton; + + private Button cardinalSouthRadioButton; + + private Button cardinalEastRadioButton; + + private Button cardinalWestRadioButton; + + Combo resolutionCombo; + + Group rootContainer; + + PointEditDialog parent; + + private CoordinateInputOptions currInputMode = CoordinateInputOptions.DEGREES_MINUTES_SECONDS; + + public CoordinateInputPanel(PointEditDialog p, Group container) { + rootContainer = container; + parent = p; + init(); + } + + private void init() { + GridData gd = null; + rootContainer.setLayout(new GridLayout(5, false)); + gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, true, false); + gd.minimumWidth = 340; + rootContainer.setLayoutData(gd); + + Label lblLat = new Label(rootContainer, SWT.NONE); + lblLat.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_MEDIUM, SWT.BOLD)); + lblLat.setAlignment(SWT.CENTER); + gd = new GridData(SWT.LEFT, SWT.CENTER, false, false); + lblLat.setLayoutData(gd); + lblLat.setText("Lat:"); + + latDegreesText = new Text(rootContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 64; + latDegreesText.setLayoutData(gd); + + latMinutesText = new Text(rootContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 64; + latMinutesText.setLayoutData(gd); + + latSecondsText = new Text(rootContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 64; + latSecondsText.setLayoutData(gd); + + latDegreesText.addFocusListener(new FocusListener() { + + @Override + public void focusGained(FocusEvent e) { + latDegreesText.selectAll(); + } + + @Override + public void focusLost(FocusEvent e) { + String degreesStr = latDegreesText.getText(); + if ((degreesStr == null) || (degreesStr.length() == 0)) + return; + float degrees = Float.parseFloat(degreesStr); + if (degrees < 0.0) { + cardinalSouthRadioButton.setSelection(true); + cardinalNorthRadioButton.setSelection(false); + degrees = Math.abs(degrees); + degreesStr = Float.toString(degrees); + latDegreesText.setText(degreesStr); + } + } + + }); + + Composite latRadioGroupComposite = new Composite(rootContainer, + SWT.NONE); + latRadioGroupComposite.setLayout(new GridLayout(2, true)); + + cardinalNorthRadioButton = new Button(latRadioGroupComposite, SWT.RADIO); + cardinalNorthRadioButton.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.BOLD)); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 35; + cardinalNorthRadioButton.setLayoutData(gd); + cardinalNorthRadioButton.setText("N"); + + cardinalSouthRadioButton = new Button(latRadioGroupComposite, SWT.RADIO); + cardinalSouthRadioButton.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.BOLD)); + cardinalSouthRadioButton.setText("S"); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 35; + cardinalSouthRadioButton.setLayoutData(gd); + + new Label(rootContainer, SWT.NONE); + + Label lblDegrees = new Label(rootContainer, SWT.NONE); + lblDegrees.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.NORMAL)); + lblDegrees.setAlignment(SWT.CENTER); + gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gd.horizontalSpan = 1; + lblDegrees.setLayoutData(gd); + lblDegrees.setText("degrees"); + + Label lblMinutes = new Label(rootContainer, SWT.NONE); + lblMinutes.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.NORMAL)); + lblMinutes.setAlignment(SWT.CENTER); + gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + lblMinutes.setLayoutData(gd); + lblMinutes.setText("minutes"); + + Label lblSeconds = new Label(rootContainer, SWT.NONE); + lblSeconds.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.NORMAL)); + lblSeconds.setAlignment(SWT.CENTER); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + lblSeconds.setLayoutData(gd); + lblSeconds.setText("seconds"); + + new Label(rootContainer, SWT.NONE); + + Label lblLon = new Label(rootContainer, SWT.NONE); + lblLon.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_MEDIUM, SWT.BOLD)); + lblLon.setAlignment(SWT.CENTER); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + lblLon.setLayoutData(gd); + lblLon.setText("Lon:"); + + lonDegreesText = new Text(rootContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 64; + lonDegreesText.setLayoutData(gd); + + lonDegreesText.addFocusListener(new FocusListener() { + + @Override + public void focusGained(FocusEvent e) { + lonDegreesText.selectAll(); + } + + @Override + public void focusLost(FocusEvent e) { + String degreesStr = lonDegreesText.getText(); + if ((degreesStr == null) || (degreesStr.length() == 0)) + return; + float degrees = Float.parseFloat(degreesStr); + if (degrees < 0.0) { + cardinalWestRadioButton.setSelection(true); + cardinalEastRadioButton.setSelection(false); + degrees = Math.abs(degrees); + degreesStr = Float.toString(degrees); + lonDegreesText.setText(degreesStr); + } + } + }); + + lonMinutesText = new Text(rootContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 64; + lonMinutesText.setLayoutData(gd); + + lonSecondsText = new Text(rootContainer, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 64; + lonSecondsText.setLayoutData(gd); + + Composite lonRadioGroupComposite = new Composite(rootContainer, + SWT.NONE); + lonRadioGroupComposite.setLayout(new GridLayout(2, true)); + + cardinalWestRadioButton = new Button(lonRadioGroupComposite, SWT.RADIO); + cardinalWestRadioButton.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.BOLD)); + cardinalWestRadioButton.setText("W"); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + gd.minimumWidth = 35; + cardinalWestRadioButton.setLayoutData(gd); + + cardinalEastRadioButton = new Button(lonRadioGroupComposite, SWT.RADIO); + cardinalEastRadioButton.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_SMALL, SWT.BOLD)); + cardinalEastRadioButton.setText("E"); + gd = new GridData(SWT.CENTER, SWT.CENTER, true, false); + cardinalEastRadioButton.setLayoutData(gd); + gd.minimumWidth = 35; + + cardinalNorthRadioButton.setSelection(true); + cardinalWestRadioButton.setSelection(true); + + new Label(rootContainer, SWT.NONE); + resolutionCombo = new Combo(rootContainer, SWT.SINGLE | SWT.CENTER + | SWT.READ_ONLY); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.horizontalSpan = 3; + resolutionCombo.setLayoutData(gd); + resolutionCombo.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_MEDIUM, SWT.NORMAL)); + resolutionCombo.add(DEGREES_MINUTES_SECONDS); + resolutionCombo.add(DEGREES_MINUTES); + resolutionCombo.add(DEGREES_ONLY); + resolutionCombo.select(0); + + resolutionCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + handleInputConstraintEvent(); + } + }); + new Label(rootContainer, SWT.NONE); + } + + protected void setLatDegrees(double d) { + String cs = String.format("%.5f", d); + latDegreesText.setText(cs); + } + + protected void setLatDegrees(int i) { + latDegreesText.setText(Integer.toString(i)); + } + + protected void setLatMinutes(double d) { + String cs = String.format("%.4f", d); + latMinutesText.setText(cs); + } + + protected void setLatMinutes(int i) { + latMinutesText.setText(Integer.toString(i)); + } + + protected void setLatMinutes(String s) { + latMinutesText.setText(s); + } + + protected void setLatSeconds(double d) { + String cs = String.format("%.3f", d); + latSecondsText.setText(cs); + } + + protected void setLatSeconds(String s) { + latSecondsText.setText(s); + } + + protected void setLonDegrees(double d) { + String cs = String.format("%.5f", d); + lonDegreesText.setText(cs); + } + + protected void setLonMinutes(double d) { + String cs = String.format("%.4f", d); + lonMinutesText.setText(cs); + } + + protected void setLonMinutes(String s) { + lonMinutesText.setText(s); + } + + protected void setLonDegrees(int d) { + lonDegreesText.setText(Integer.toString(d)); + } + + protected void setLonMinutes(int d) { + lonMinutesText.setText(Integer.toString(d)); + } + + protected void setLonSeconds(double d) { + String cs = String.format("%.3f", d); + lonSecondsText.setText(cs); + } + + protected void setLonSeconds(String s) { + lonSecondsText.setText(s); + } + + protected void setWest(boolean f) { + cardinalWestRadioButton.setSelection(f); + cardinalEastRadioButton.setSelection(!f); + } + + protected void setNorth(boolean f) { + cardinalNorthRadioButton.setSelection(f); + cardinalSouthRadioButton.setSelection(!f); + } + + protected boolean isWest() { + return cardinalWestRadioButton.getSelection(); + } + + protected boolean isNorth() { + return cardinalNorthRadioButton.getSelection(); + } + + protected double getLatDegrees() { + double deg = 0.0; + try { + deg = Double.parseDouble(latDegreesText.getText()); + } catch (Exception e) { + deg = 0.0; + } + return deg; + } + + protected double getLatMinutes() { + double min = 0.0; + try { + min = Double.parseDouble(latMinutesText.getText()); + } catch (Exception e) { + min = 0.0; + } + return min; + } + + protected double getLatSeconds() { + double sec = 0.0; + try { + sec = Double.parseDouble(latSecondsText.getText()); + } catch (Exception e) { + sec = 0.0; + } + return sec; + } + + protected double getLonDegrees() { + double deg = 0.0; + try { + deg = Double.parseDouble(lonDegreesText.getText()); + } catch (Exception e) { + deg = 0.0; + } + return deg; + } + + protected double getLonMinutes() { + double min = 0.0; + try { + min = Double.parseDouble(lonMinutesText.getText()); + } catch (Exception e) { + min = 0.0; + } + return min; + } + + protected double getLonSeconds() { + double sec = 0.0; + try { + sec = Double.parseDouble(lonSecondsText.getText()); + } catch (Exception e) { + sec = 0.0; + } + return sec; + } + + public double getLatAsDegreesOnly() { + double degrees = 0.0; + + CoordinateInputOptions c = getInputMode(); + + if (c == CoordinateInputOptions.DEGREES_MINUTES_SECONDS) { + degrees = getLatDegrees() + + (getLatMinutes() / PointUtilities.MINUTE_PER_DEGREE) + + (getLatSeconds() / (PointUtilities.SECOND_PER_MINUTE * PointUtilities.MINUTE_PER_DEGREE)); + } else if (c == CoordinateInputOptions.DEGREES_MINUTES) { + degrees = getLatDegrees() + + (getLatMinutes() / PointUtilities.MINUTE_PER_DEGREE); + } else if (c == CoordinateInputOptions.DEGREES_ONLY) { + degrees = getLatDegrees(); + } + + if (!isNorth()) { + degrees *= -1; + } + + return degrees; + } + + public double getLonAsDegreesOnly() { + double degrees = 0.0; + + CoordinateInputOptions c = getInputMode(); + + if (c == CoordinateInputOptions.DEGREES_MINUTES_SECONDS) { + degrees = getLonDegrees() + + (getLonMinutes() / PointUtilities.MINUTE_PER_DEGREE) + + (getLonSeconds() / (PointUtilities.MINUTE_PER_DEGREE * PointUtilities.SECOND_PER_MINUTE)); + } else if (c == CoordinateInputOptions.DEGREES_MINUTES) { + degrees = getLonDegrees() + + (getLonMinutes() / PointUtilities.MINUTE_PER_DEGREE); + } else if (c == CoordinateInputOptions.DEGREES_ONLY) { + degrees = getLonDegrees(); + } + + if (isWest()) { + degrees *= -1; + } + + return degrees; + } + + protected void normalizeLatToDegreesOnly(double origLat, boolean isRaw) { + + if (isRaw) { + if (origLat < 0) { + setNorth(false); + } else { + setNorth(true); + } + } + double absLat = Math.abs(origLat); + + setLatDegrees(absLat); + setLatMinutes(PointEditDialog.NOT_ENABLED); + setLatSeconds(PointEditDialog.NOT_ENABLED); + } + + protected void normalizeLatToDegreesMinutes(double origLat, boolean isRaw) { + + if (isRaw) { + if (origLat < 0) { + setNorth(false); + } else { + setNorth(true); + } + } + + double deg = 0.0; + double min = 0.0; + double absLat = Math.abs(origLat); + + if ((absLat != 0) && (absLat != PointUtilities.MAX_LATITUDE)) { + deg = Math.floor(absLat); + min = ((absLat - deg) * PointUtilities.MINUTE_PER_DEGREE); + } else { + deg = absLat; + } + + int iDeg = (int) deg; + setLatDegrees(iDeg); + setLatMinutes(min); + setLatSeconds(PointEditDialog.NOT_ENABLED); + } + + protected void normalizeLatToDegreesMinutesSeconds(double origLat, + boolean isRaw) { + + if (isRaw) { + if (origLat < 0) { + setNorth(false); + } else { + setNorth(true); + } + } + + double deg = 0.0; + double min = 0.0; + double sec = 0.0; + double absLat = Math.abs(origLat); + + if ((absLat != 0) && (absLat != PointUtilities.MAX_LATITUDE)) { + deg = Math.floor(absLat); + min = Math.floor((absLat - deg) * PointUtilities.MINUTE_PER_DEGREE); + sec = (absLat - deg - (min / PointUtilities.MINUTE_PER_DEGREE)) + * (PointUtilities.MINUTE_PER_DEGREE * PointUtilities.SECOND_PER_MINUTE); + } else { + deg = absLat; + } + + int iDeg = (int) deg; + int iMin = (int) min; + setLatDegrees(iDeg); + setLatMinutes(iMin); + setLatSeconds(sec); + } + + protected void normalizeLonToDegreesOnly(double origLon, boolean isRaw) { + + if (isRaw) { + if (origLon < 0) { + setWest(true); + } else { + setWest(false); + } + } + + double absLon = Math.abs(origLon); + setLonDegrees(absLon); + setLonMinutes(PointEditDialog.NOT_ENABLED); + setLonSeconds(PointEditDialog.NOT_ENABLED); + } + + protected void normalizeLonToDegreesMinutes(double origLon, boolean isRaw) { + + if (isRaw) { + if (origLon < 0) { + setWest(true); + } else { + setWest(false); + } + } + + double deg = 0.0; + double min = 0.0; + double absLon = Math.abs(origLon); + + if ((absLon != 0) && (absLon != PointUtilities.MAX_LONGITUDE)) { + deg = Math.floor(absLon); + min = (absLon - deg) * PointUtilities.MINUTE_PER_DEGREE; + } else { + deg = absLon; + } + + int iDeg = (int) deg; + setLonDegrees(iDeg); + setLonMinutes(min); + setLonSeconds(PointEditDialog.NOT_ENABLED); + + } + + protected void normalizeLonToDegreesMinutesSeconds(double origLon, + boolean isRaw) { + + if (isRaw) { + if (origLon < 0) { + setWest(true); + } else { + setWest(false); + } + } + + double deg = 0.0; + double min = 0.0; + double sec = 0.0; + double absLon = Math.abs(origLon); + + if ((absLon != 0) && (absLon != PointUtilities.MAX_LONGITUDE)) { + deg = Math.floor(absLon); + min = Math.floor((absLon - deg) * PointUtilities.MINUTE_PER_DEGREE); + sec = (absLon - deg - (min / PointUtilities.MINUTE_PER_DEGREE)) + * (PointUtilities.MINUTE_PER_DEGREE * PointUtilities.SECOND_PER_MINUTE); + } else { + deg = absLon; + } + + int iDeg = (int) deg; + int iMin = (int) min; + setLonDegrees(iDeg); + setLonMinutes(iMin); + setLonSeconds(sec); + + } + + protected CoordinateInputOptions getInputMode() { + return currInputMode; + } + + private void handleInputConstraintEvent() { + + int index = resolutionCombo.getSelectionIndex(); + if (index == CoordinateInputOptions.DEGREES_MINUTES_SECONDS + .getOrdinal()) { + currInputMode = CoordinateInputOptions.DEGREES_MINUTES_SECONDS; + recalculateCoordinateFields(); + latDegreesText.setEnabled(true); + latMinutesText.setEnabled(true); + latSecondsText.setEnabled(true); + lonDegreesText.setEnabled(true); + lonMinutesText.setEnabled(true); + lonSecondsText.setEnabled(true); + } else if (index == CoordinateInputOptions.DEGREES_MINUTES.getOrdinal()) { + currInputMode = CoordinateInputOptions.DEGREES_MINUTES; + recalculateCoordinateFields(); + latDegreesText.setEnabled(true); + latMinutesText.setEnabled(true); + latSecondsText.setEnabled(false); + lonDegreesText.setEnabled(true); + lonMinutesText.setEnabled(true); + lonSecondsText.setEnabled(false); + } else if (index == CoordinateInputOptions.DEGREES_ONLY.getOrdinal()) { + currInputMode = CoordinateInputOptions.DEGREES_ONLY; + recalculateCoordinateFields(); + latDegreesText.setEnabled(true); + latMinutesText.setEnabled(false); + latSecondsText.setEnabled(false); + lonDegreesText.setEnabled(true); + lonMinutesText.setEnabled(false); + lonSecondsText.setEnabled(false); + } + if (resolutionCombo.isFocusControl()) { + parent.resetFocus(); + } + + } + + public void recalculateCoordinateFields(Coordinate latLon) { + recalculateCoordinateFields(latLon.y, latLon.x); + } + + protected void recalculateCoordinateFields(Point currentPoint) { + recalculateCoordinateFields(currentPoint.getLatitude(), + currentPoint.getLongitude()); + } + + protected void recalculateCoordinateFields(double lat, double lon) { + CoordinateInputOptions c = getInputMode(); + + if (c == CoordinateInputOptions.DEGREES_MINUTES_SECONDS) { + normalizeLatToDegreesMinutesSeconds(lat, true); + normalizeLonToDegreesMinutesSeconds(lon, true); + } else if (c == CoordinateInputOptions.DEGREES_MINUTES) { + normalizeLatToDegreesMinutes(lat, true); + normalizeLonToDegreesMinutes(lon, true); + + } else if (c == CoordinateInputOptions.DEGREES_ONLY) { + normalizeLatToDegreesOnly(lat, true); + normalizeLonToDegreesOnly(lon, true); + } + } + + protected void recalculateCoordinateFields() { + double origLat = getLatDegrees() + (getLatMinutes() / 60) + + (this.getLatSeconds() / 3600); + double origLon = getLonDegrees() + (getLonMinutes() / 60) + + (this.getLonSeconds() / 3600); + if (currInputMode == CoordinateInputOptions.DEGREES_MINUTES_SECONDS) { + normalizeLatToDegreesMinutesSeconds(origLat, false); + normalizeLonToDegreesMinutesSeconds(origLon, false); + } else if (currInputMode == CoordinateInputOptions.DEGREES_MINUTES) { + normalizeLatToDegreesMinutes(origLat, false); + normalizeLonToDegreesMinutes(origLon, false); + + } else if (currInputMode == CoordinateInputOptions.DEGREES_ONLY) { + normalizeLatToDegreesOnly(origLat, false); + normalizeLonToDegreesOnly(origLon, false); + } + } + + private enum CoordinateInputOptions { + DEGREES_MINUTES_SECONDS(0), DEGREES_MINUTES(1), DEGREES_ONLY(2); + + private int _ordinal = 0; + + CoordinateInputOptions(int index) { + _ordinal = index; + } + + public int getOrdinal() { + return _ordinal; + } + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/FontManager.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/FontManager.java new file mode 100644 index 0000000000..4547860988 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/FontManager.java @@ -0,0 +1,70 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.jface.resource.FontRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; + +/** + * Class with a static method for obtaining a font. This handles registering the + * requested font so disposing of the font is taken care of. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31 2012  #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + */ +public class FontManager { + private FontManager() { + + } + + /** + * Returns the font based on its name, height and style. + * + * @param name + * the name of the font (must not be null) + * @param height + * the font height in points + * @param style + * a bitwise combination of NORMAL, ITALIC and BOLD + * @return font + */ + public static Font getFont(String name, int size, int style) { + FontRegistry registry = JFaceResources.getFontRegistry(); + String symbolicName = name + '|' + size + '|' + style; + Font font = registry.get(symbolicName); + if (font == null) { + FontData fontData = new FontData(name, size, style); + registry.put(symbolicName, new FontData[] { fontData }); + font = registry.get(symbolicName); + } + return font; + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointDecoratingLabelProvider.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointDecoratingLabelProvider.java new file mode 100644 index 0000000000..cdfaff4841 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointDecoratingLabelProvider.java @@ -0,0 +1,81 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.jface.viewers.DecoratingLabelProvider; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.graphics.Image; + +/** + * Class to properly display the columns of a maker node. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation.
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointDecoratingLabelProvider extends DecoratingLabelProvider + implements ITableLabelProvider { + + ITableLabelProvider provider; + + ILabelDecorator decorator; + + public PointDecoratingLabelProvider(ILabelProvider provider, + ILabelDecorator decorator) { + super(provider, decorator); + this.provider = (ITableLabelProvider) provider; + this.decorator = decorator; + } + + @Override + public Image getColumnImage(Object element, int columnIndex) { + Image image = provider.getColumnImage(element, columnIndex); + if (decorator != null) { + Image decorated = decorator.decorateImage(image, element); + if (decorated != null) { + return decorated; + } + } + return image; + } + + @Override + public String getColumnText(Object element, int columnIndex) { + String text = provider.getColumnText(element, columnIndex); + if (decorator != null) { + String decorated = decorator.decorateText(text, element); + if (decorated != null) { + return decorated; + } + } + return text; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointEditDialog.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointEditDialog.java new file mode 100644 index 0000000000..8b00d84f1a --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointEditDialog.java @@ -0,0 +1,631 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.FocusEvent; +import org.eclipse.swt.events.FocusListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.points.PointUtilities; +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointFieldState; +import com.raytheon.uf.viz.points.data.PointSize; +import com.raytheon.uf.viz.points.ui.layer.PointsToolLayer; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; +import com.raytheon.viz.ui.dialogs.ICloseCallback; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Dialog for getting values for a point. + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ *  October-2010              epolster    Initial Creation.
+ *  Jul 31, 2012 #875         rferrel    Implements groups, hidden and
+ *                                        assign color.
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointEditDialog extends CaveJFACEDialog { + + private enum EditOptions { + CREATE_FROM_SCRATCH, EDIT, CREATE_AT_LOCATION; + } + + public static Point MOST_RECENTLY_MODIFIED_POINT = null; + + static private final int VALIDATE_FIRST_CURSOR_ID = IDialogConstants.CLIENT_ID + 4; + + final int MAX_LATITUDE = 90; + + final int MAX_LONGITUDE = 180; + + final double MINUTE_PER_DEGREE = 60; + + final double SECOND_PER_MINUTE = 60; + + static final public int PREFERRED_FONT_SIZE_MEDIUM = 9; + + static final public int PREFERRED_FONT_SIZE_SMALL = 8; + + static protected String NOT_ENABLED = "---"; + + static private final String COLOR_CHOOSER_TITLE = "Change Point Color"; + + final private Font DIALOG_FONT_MEDIUM = FontManager.getFont("Tahoma", + PREFERRED_FONT_SIZE_MEDIUM, SWT.BOLD); + + final private Font DIALOG_FONT_SMALL = FontManager.getFont("Tahoma", + PREFERRED_FONT_SIZE_SMALL, SWT.NORMAL); + + private Composite rootContainer; + + private Text pointNameText; + + private Button pointColorChooserButton; + + private Button pointMovableButton; + + private Button pointHiddenButton; + + private Button pointAssignColorButton; + + private Combo pointFontSizeChooser; + + private Combo pointGroupChooser; + + protected CoordinateInputPanel coordinateInput; + + private Coordinate createAtLocation = null; + + private EditOptions dialogFlavor; + + private Point currPoint; + + private Color currColor; + + private PointsToolLayer toolLayer; + + /** + * Generates a non-blocking Point Edit dialog for creating a new point. + * Except for the point name the defaultPoint is used to populate the + * initial values of the dialog. When the dialog is closed by the OK button + * the returnValue is a point with the values from the dialog otherwise + * returnValue is null. + * + * @param layer + * @param defaultPoint + * @param cb + * - Closed callback called when dialog is closed + */ + static public void createNewPointViaDialog(PointsToolLayer layer, + Point defaultPoint, final ICloseCallback cb) { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + PointEditDialog dlg = new PointEditDialog(shell, layer, + EditOptions.CREATE_FROM_SCRATCH, defaultPoint); + dlg.setBlockOnOpen(false); + dlg.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + int ret = ((Integer) returnValue).intValue(); + if (ret != Window.OK) { + MOST_RECENTLY_MODIFIED_POINT = null; + } + if (cb != null) { + cb.dialogClosed(MOST_RECENTLY_MODIFIED_POINT); + } + } + }); + dlg.open(); + } + + /** + * Generates a non-blocking Point Edit dialog for editing an existing point. + *When the dialog is closed by the OK button + * the returnValue is a point with the values from the dialog otherwise + * returnValue is null. + * @param layer + * @param point + * @param cb - Closed callback called when dialog is closed + */ + static public void editPointViaDialog(PointsToolLayer layer, Point point, + final ICloseCallback cb) { + Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell(); + PointEditDialog dlg = new PointEditDialog(shell, layer, + EditOptions.EDIT, point); + dlg.setBlockOnOpen(false); + dlg.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + int ret = ((Integer) returnValue).intValue(); + if (ret != Window.OK) { + MOST_RECENTLY_MODIFIED_POINT = null; + } + if (cb != null) { + cb.dialogClosed(MOST_RECENTLY_MODIFIED_POINT); + } + } + }); + dlg.open(); + } + + private PointEditDialog(Shell parentShell, PointsToolLayer layer, + EditOptions meo) { + super(parentShell); + toolLayer = layer; + dialogFlavor = meo; + currPoint = null; + } + + private PointEditDialog(Shell parentShell, PointsToolLayer layer, + EditOptions meo, Point cm) { + super(parentShell); + toolLayer = layer; + dialogFlavor = meo; + currPoint = cm; + } + + private PointEditDialog(Shell parentShell, PointsToolLayer layer, + EditOptions meo, Coordinate atLocation) { + super(parentShell); + toolLayer = layer; + createAtLocation = atLocation; + dialogFlavor = meo; + currPoint = null; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets + * .Shell) + */ + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + if (dialogFlavor == EditOptions.CREATE_AT_LOCATION) { + newShell.setText("Create Point At Location"); + } else if (dialogFlavor == EditOptions.CREATE_FROM_SCRATCH) { + newShell.setText("Create Point"); + } else if (dialogFlavor == EditOptions.EDIT) { + newShell.setText("Edit Point"); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveJFACEDialog#createDialogArea(org.eclipse + * .swt.widgets.Composite) + */ + + @Override + protected Control createDialogArea(Composite parent) { + rootContainer = (Composite) super.createDialogArea(parent); + rootContainer.setLayout(new GridLayout(1, true)); + + // create group components + createPointNameGroup(); + createLocationGroup(); + createPropertiesGroup(); + + if (dialogFlavor == EditOptions.CREATE_AT_LOCATION) { + initForCreateAtPosition(true); + } else if (dialogFlavor == EditOptions.CREATE_FROM_SCRATCH) { + initForCreateFromScratch(); + } else if (dialogFlavor == EditOptions.EDIT) { + initForEdit(); + } + + pointNameText.addFocusListener(new FocusListener() { + + @Override + public void focusGained(FocusEvent e) { + pointNameText.selectAll(); + } + + @Override + public void focusLost(FocusEvent e) { + String pointName = pointNameText.getText(); + if ((pointName == null) || (pointName.length() == 0)) { + return; + } else { + pointName = PointUtilities.trimAll(pointName); + pointNameText.setText(pointName); + } + } + }); + + applyDialogFont(rootContainer); + return rootContainer; + } + + private void createPointNameGroup() { + Group group = new Group(rootContainer, SWT.NONE); + GridData gd = null; + group.setLayout(new GridLayout(2, false)); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + group.setLayoutData(gd); + Label label = new Label(group, SWT.CENTER); + label.setFont(DIALOG_FONT_MEDIUM); + gd = new GridData(SWT.LEFT, SWT.CENTER, false, false); + label.setLayoutData(gd); + label.setText("Point Name:"); + + pointNameText = new Text(group, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + pointNameText.setLayoutData(gd); + } + + private void createLocationGroup() { + Group group = new Group(rootContainer, SWT.NONE); + coordinateInput = new CoordinateInputPanel(this, group); + } + + private void createPropertiesGroup() { + Group group = new Group(rootContainer, SWT.NO_RADIO_GROUP); + Label vs = null; + GridData gd = null; + + group.setLayout(new GridLayout(5, false)); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + group.setLayoutData(gd); + + pointAssignColorButton = new Button(group, SWT.CHECK); + pointAssignColorButton.setFont(DIALOG_FONT_SMALL); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + pointAssignColorButton.setLayoutData(gd); + // activeColorButton.setBounds(9, 10, 120, 17); + pointAssignColorButton.setText("Assign Color"); + pointAssignColorButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + pointColorChooserButton.setEnabled(pointAssignColorButton + .getSelection()); + } + }); + + vs = new Label(group, SWT.SEPARATOR | SWT.VERTICAL); + gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + gd.verticalSpan = 2; + vs.setLayoutData(gd); + + pointGroupChooser = new Combo(group, SWT.SINGLE | SWT.READ_ONLY); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + pointGroupChooser.setLayoutData(gd); + pointGroupChooser.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_MEDIUM, SWT.NORMAL)); + String[] groups = PointsDataManager.getInstance().getGroupList(); + pointGroupChooser.add(""); + for (String grp : groups) { + pointGroupChooser.add(grp); + } + + vs = new Label(group, SWT.SEPARATOR | SWT.VERTICAL); + gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + gd.verticalSpan = 2; + vs.setLayoutData(gd); + + pointHiddenButton = new Button(group, SWT.CHECK); + pointHiddenButton.setFont(DIALOG_FONT_SMALL); + gd = new GridData(SWT.LEFT, SWT.CENTER, false, false); + pointHiddenButton.setLayoutData(gd); + pointHiddenButton.setText("Hidden"); + pointColorChooserButton = new Button(group, SWT.NONE); + pointColorChooserButton.setFont(DIALOG_FONT_SMALL); + gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + pointColorChooserButton.setLayoutData(gd); + pointColorChooserButton.setText("Change Color"); + + RGB color = null; + if (currPoint != null && currPoint.isColorActive()) { + color = currPoint.getColor(); + } + setCurrentColor(color); + + pointColorChooserButton.setBackground(currColor); + pointColorChooserButton.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + ColorDialog dlg = new ColorDialog(getShell()); + dlg.setRGB(currColor.getRGB()); + dlg.setText(COLOR_CHOOSER_TITLE); + RGB result = dlg.open(); + if (result != null) { + setCurrentColor(result); + pointColorChooserButton.setBackground(currColor); + } + } + }); + + pointFontSizeChooser = new Combo(group, SWT.SINGLE | SWT.READ_ONLY); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + pointFontSizeChooser.setLayoutData(gd); + pointFontSizeChooser.setFont(FontManager.getFont("Tahoma", + PointEditDialog.PREFERRED_FONT_SIZE_MEDIUM, SWT.NORMAL)); + + for (PointSize ps : PointSize.values()) { + pointFontSizeChooser.add(ps.getReadableName()); + } + if (currPoint != null) { + pointFontSizeChooser.select(currPoint.getFontSize().ordinal()); + } else { + pointFontSizeChooser.select(0); + } + + pointMovableButton = new Button(group, SWT.CHECK); + pointMovableButton.setFont(DIALOG_FONT_SMALL); + pointMovableButton.setText("Movable"); + gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + } + + protected void resetFocus() { + pointNameText.setFocus(); + } + + /** + * Create contents of the button bar. + * + * @param parent + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + final PointEditDialog dialog = this; + + Button okButton = createButton(parent, VALIDATE_FIRST_CURSOR_ID, + IDialogConstants.OK_LABEL, true); + okButton.addSelectionListener(new SelectionListener() { + + @Override + public void widgetDefaultSelected(SelectionEvent e) { + } + + @Override + public void widgetSelected(SelectionEvent e) { + if (dialog.acceptChanges()) { + dialog.close(); + } else { + resetFocus(); + } + } + }); + + createButton(parent, IDialogConstants.CANCEL_ID, + IDialogConstants.CANCEL_LABEL, false); + } + + protected boolean acceptChanges() { + + String name = pointNameText.getText(); + if ((name == null) || (name.trim().length() == 0)) { + MessageBox d = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + d.setMessage("You must provide a name for the point."); + d.open(); + return false; + } + + if (!PointUtilities.isValidFileName(name)) { + MessageBox d = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + d.setMessage("Point names can contain only letters, numbers, underscores, and spaces."); + d.open(); + return false; + } + + double lat = coordinateInput.getLatAsDegreesOnly(); + if ((lat < (PointUtilities.MAX_LATITUDE * -1)) + || (lat > PointUtilities.MAX_LATITUDE)) { + MessageBox d = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + d.setMessage("Please enter a valid latitude."); + d.open(); + return false; + } + + double lon = coordinateInput.getLonAsDegreesOnly(); + if ((lon < (PointUtilities.MAX_LONGITUDE * -1)) + || (lon > PointUtilities.MAX_LONGITUDE)) { + MessageBox d = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + d.setMessage("Please enter a valid longitude."); + d.open(); + return false; + } + + MOST_RECENTLY_MODIFIED_POINT = createPointFromInput(); + boolean alreadyExists = PointsDataManager.getInstance().exists( + MOST_RECENTLY_MODIFIED_POINT.getName()); + + // if we are creating a new point then it can't be a duplicate + if (dialogFlavor != EditOptions.EDIT && alreadyExists) { + MessageBox d = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + d.setMessage("Duplicate point name not allowed."); + d.open(); + return false; + } else if (alreadyExists + && !currPoint.getName().equals( + MOST_RECENTLY_MODIFIED_POINT.getName())) { + MessageBox d = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK); + d.setMessage("Point's new name is a duplicate; and not allowed."); + d.open(); + return false; + } + + return true; + } + + public void initForEdit() { + + pointNameText.setText(currPoint.getName()); + coordinateInput.recalculateCoordinateFields(currPoint); + pointFontSizeChooser.select(currPoint.getFontSize().ordinal()); + pointMovableButton + .setSelection(currPoint.getMovable() == PointFieldState.TRUE); + pointHiddenButton + .setSelection(currPoint.getHidden() == PointFieldState.TRUE); + RGB color = currPoint.getColor(); + setCurrentColor(color); + pointAssignColorButton.setSelection(currPoint.isColorActive()); + pointColorChooserButton.setEnabled(currPoint.isColorActive()); + pointColorChooserButton.setBackground(currColor); + int index = pointGroupChooser.indexOf(currPoint.getGroup().replace( + PointUtilities.DELIM_CHAR, ' ')); + if (index < 0) { + index = 0; + } + pointGroupChooser.select(index); + resetFocus(); + + } + + public void initForCreateAtPosition(boolean firstTimeThru) { + + pointNameText.setEditable(true); + pointNameText.setEnabled(true); + if (firstTimeThru) { + pointNameText.setText(""); + } + coordinateInput.recalculateCoordinateFields(createAtLocation); + + resetFocus(); + + pointFontSizeChooser.select(PointSize.DEFAULT.ordinal()); + pointMovableButton.setSelection(false); + pointHiddenButton.setSelection(false); + } + + protected void initForCreateFromScratch() { + + if (currPoint != null) { + initForEdit(); + } else { + pointNameText.setEditable(true); + pointNameText.setEnabled(true); + coordinateInput.setLatDegrees(0); + coordinateInput.setLatMinutes(0); + coordinateInput.setLatSeconds(0.0f); + + coordinateInput.setLonDegrees(0); + coordinateInput.setLonMinutes(0); + coordinateInput.setLonSeconds(0.0f); + resetFocus(); + + coordinateInput.setNorth(true); + coordinateInput.setWest(true); + pointFontSizeChooser.select(PointSize.DEFAULT.ordinal()); + pointMovableButton.setSelection(true); + pointHiddenButton.setSelection(false); + pointAssignColorButton.setSelection(false); + pointColorChooserButton.setEnabled(false); + pointGroupChooser.select(0); + } + pointNameText.setText(""); + } + + /** + * Generate a point based on the user information provided by the dialog. + * This assumes validation of of the input has already been performed. + * + * @return point + */ + private Point createPointFromInput() { + + String name = pointNameText.getText(); + boolean colorActive = pointAssignColorButton.getSelection(); + double latDeg = coordinateInput.getLatAsDegreesOnly(); + double lonDeg = coordinateInput.getLonAsDegreesOnly(); + int ordinal = pointFontSizeChooser.getSelectionIndex(); + PointFieldState movable = pointMovableButton.getSelection() ? PointFieldState.TRUE + : PointFieldState.FALSE; + String group = ""; + int selIndex = pointGroupChooser.getSelectionIndex(); + if (selIndex > 0) { + group = pointGroupChooser.getItem(selIndex); + } + PointFieldState hidden = pointHiddenButton.getSelection() ? PointFieldState.TRUE + : PointFieldState.FALSE; + Point point = new Point(name, latDeg, lonDeg, movable, colorActive, + currColor.getRGB(), PointSize.getPointSize(ordinal), group); + point.setHidden(hidden); + return point; + } + + private void setCurrentColor(RGB rgb) { + if (rgb == null) { + rgb = toolLayer.getCapability(ColorableCapability.class).getColor(); + } + + if (currColor != null) { + if (currColor.getRed() == rgb.red + && currColor.getGreen() == rgb.green + && currColor.getBlue() == rgb.blue) { + return; + } + currColor.dispose(); + } + Display display = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getShell().getDisplay(); + currColor = new Color(display, rgb); + } + + @Override + public boolean close() { + if (currColor != null) { + currColor.dispose(); + currColor = null; + } + return super.close(); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointHiddenEditingSupport.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointHiddenEditingSupport.java new file mode 100644 index 0000000000..e1c33bf644 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointHiddenEditingSupport.java @@ -0,0 +1,131 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointNameChangeException; +import com.raytheon.uf.viz.points.data.PointFieldState; +import com.raytheon.uf.viz.points.ui.dialog.TriStateCellEditor.STATE; +import com.raytheon.uf.viz.points.ui.layer.PointsToolLayer; + +/** + * Class to support editing of hidden column. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointHiddenEditingSupport extends EditingSupport { + + private PointsToolLayer toolLayer; + + private TriStateCellEditor cellEditor; + + public PointHiddenEditingSupport(TreeViewer viewer, PointsToolLayer layer) { + super(viewer); + toolLayer = layer; + cellEditor = new TriStateCellEditor( + (Composite) viewer.getContentProvider(), SWT.READ_ONLY); + } + + @Override + protected CellEditor getCellEditor(Object element) { + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + IPointNode node = (IPointNode) element; + STATE value = STATE.GRAYED; + switch (node.getHidden()) { + case TRUE: + value = STATE.SELECTED; + break; + case FALSE: + value = STATE.UNSELECTED; + break; + case UNKNOWN: + value = STATE.GRAYED; + break; + default: + Assert.isTrue(false); + } + return value; + } + + @Override + protected void setValue(Object element, Object value) { + IPointNode node = (IPointNode) element; + STATE state = (STATE) value; + PointFieldState newValue = PointFieldState.UNKNOWN; + switch (state) { + case SELECTED: + newValue = PointFieldState.TRUE; + break; + case UNSELECTED: + newValue = PointFieldState.FALSE; + break; + case GRAYED: + newValue = PointFieldState.UNKNOWN; + break; + default: + Assert.isTrue(false); + } + try { + ((TreeViewer) getViewer()).getTree().setCursor( + Display.getCurrent().getSystemCursor(SWT.CURSOR_WAIT)); + if (!node.isGroup()) { + Point point = (Point) node; + point.setHidden(newValue); + toolLayer.updatePoint(point); + } else { + Assert.isTrue(newValue != PointFieldState.UNKNOWN); + toolLayer.updateChildrenHidden(node, newValue); + } + + } catch (PointNameChangeException e) { + // ignore as point name is not being changed ... + e.printStackTrace(); + } + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointMovableEditingSupport.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointMovableEditingSupport.java new file mode 100644 index 0000000000..965bd8c0b8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointMovableEditingSupport.java @@ -0,0 +1,129 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.EditingSupport; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; + +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointNameChangeException; +import com.raytheon.uf.viz.points.data.PointFieldState; +import com.raytheon.uf.viz.points.ui.dialog.TriStateCellEditor.STATE; +import com.raytheon.uf.viz.points.ui.layer.PointsToolLayer; + +/** + * Class for supporting editing of the Movable column. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointMovableEditingSupport extends EditingSupport { + + private PointsToolLayer toolLayer; + + private TriStateCellEditor cellEditor; + + public PointMovableEditingSupport(TreeViewer viewer, PointsToolLayer layer) { + super(viewer); + toolLayer = layer; + cellEditor = new TriStateCellEditor( + (Composite) viewer.getContentProvider(), SWT.READ_ONLY); + } + + @Override + protected CellEditor getCellEditor(Object element) { + return cellEditor; + } + + @Override + protected boolean canEdit(Object element) { + return true; + } + + @Override + protected Object getValue(Object element) { + IPointNode node = (IPointNode) element; + STATE value = STATE.GRAYED; + switch (node.getMovable()) { + case TRUE: + value = STATE.SELECTED; + break; + case FALSE: + value = STATE.UNSELECTED; + break; + case UNKNOWN: + value = STATE.GRAYED; + break; + default: + Assert.isTrue(false); + } + return value; + } + + @Override + protected void setValue(Object element, Object value) { + IPointNode node = (IPointNode) element; + STATE state = (STATE) value; + PointFieldState newValue = PointFieldState.UNKNOWN; + switch (state) { + case SELECTED: + newValue = PointFieldState.TRUE; + break; + case UNSELECTED: + newValue = PointFieldState.FALSE; + break; + case GRAYED: + newValue = PointFieldState.UNKNOWN; + break; + default: + Assert.isTrue(false); + } + try { + ((TreeViewer) getViewer()).getTree().setCursor( + Display.getCurrent().getSystemCursor(SWT.CURSOR_WAIT)); + if (!node.isGroup()) { + Point point = (Point) node; + point.setMovable(newValue); + toolLayer.updatePoint(point); + } else { + Assert.isTrue(newValue != PointFieldState.UNKNOWN); + toolLayer.updateChildrenMovable(node, newValue); + } + } catch (PointNameChangeException e) { + // ignore as point name is not being changed ... + } + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeContentProvider.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeContentProvider.java new file mode 100644 index 0000000000..3ee71d6530 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeContentProvider.java @@ -0,0 +1,84 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import java.util.List; + +import org.eclipse.jface.viewers.ITreeContentProvider; +import org.eclipse.jface.viewers.Viewer; + +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.points.data.IPointNode; + +/** + * Provide the contents of a Point node. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation.
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointTreeContentProvider implements ITreeContentProvider { + + private final PointsDataManager manager = PointsDataManager.getInstance(); + + @Override + public void dispose() { + // Nothing todo but must implement the method. + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + // Nothing todo but must implement the method. + } + + @Override + public Object[] getElements(Object inputElement) { + IPointNode node = (IPointNode) inputElement; + return manager.getChildren(node, true).toArray(new IPointNode[0]); + } + + @Override + public Object[] getChildren(Object parentElement) { + IPointNode node = (IPointNode) parentElement; + List children = manager.getChildren(node, true); + return children.toArray(new IPointNode[0]); + } + + @Override + public Object getParent(Object element) { + IPointNode node = (IPointNode) element; + return manager.getParent(node); + } + + @Override + public boolean hasChildren(Object element) { + IPointNode node = (IPointNode) element; + return node.isGroup() && manager.getChildren(node, true).size() > 0; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeDragSourceListener.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeDragSourceListener.java new file mode 100644 index 0000000000..1d6ffdd7e0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeDragSourceListener.java @@ -0,0 +1,95 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.dnd.DragSourceEvent; +import org.eclipse.swt.dnd.DragSourceListener; + +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointTransfer; + +/** + * This implements a drag source listener for a Tree Viewer that contains point + * nodes. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 06, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointTreeDragSourceListener implements DragSourceListener { + + private final TreeViewer viewer; + + public PointTreeDragSourceListener(TreeViewer viewer) { + this.viewer = viewer; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.dnd.DragSourceListener#dragStart(org.eclipse.swt.dnd. + * DragSourceEvent) + */ + @Override + public void dragStart(DragSourceEvent event) { + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.dnd.DragSourceListener#dragSetData(org.eclipse.swt.dnd + * .DragSourceEvent) + */ + @SuppressWarnings("unchecked") + @Override + public void dragSetData(DragSourceEvent event) { + if (PointTransfer.getInstance().isSupportedType(event.dataType)) { + TreeSelection selection = (TreeSelection) viewer.getSelection(); + Point[] points = (Point[]) selection.toList().toArray( + new Point[selection.size()]); + event.data = points; + } + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.swt.dnd.DragSourceListener#dragFinished(org.eclipse.swt.dnd + * .DragSourceEvent) + */ + @Override + public void dragFinished(DragSourceEvent event) { + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeDropListener.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeDropListener.java new file mode 100644 index 0000000000..00eb9742a0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeDropListener.java @@ -0,0 +1,142 @@ +/***************************************************************************************** + * COPYRIGHT (c), 2007, RAYTHEON COMPANY + * ALL RIGHTS RESERVED, An Unpublished Work + * + * RAYTHEON PROPRIETARY + * If the end user is not the U.S. Government or any agency thereof, use + * or disclosure of data contained in this source code file is subject to + * the proprietary restrictions set forth in the Master Rights File. + * + * U.S. GOVERNMENT PURPOSE RIGHTS NOTICE + * If the end user is the U.S. Government or any agency thereof, this source + * code is provided to the U.S. Government with Government Purpose Rights. + * Use or disclosure of data contained in this source code file is subject to + * the "Government Purpose Rights" restriction in the Master Rights File. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * Use or disclosure of data contained in this source code file is subject to + * the export restrictions set forth in the Master Rights File. + ******************************************************************************************/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.jface.viewers.ViewerDropAdapter; +import org.eclipse.swt.dnd.DropTargetEvent; +import org.eclipse.swt.dnd.TransferData; + +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointTransfer; + +/** + * This handles moving nodes dropped onto the viewer. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Aug 15, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointTreeDropListener extends ViewerDropAdapter { + private PointsDataManager manager; + + private PointsMgrDialog dialog; + + public PointTreeDropListener(PointsMgrDialog dialog) { + super(dialog.pointsTreeViewer); + this.dialog = dialog; + this.manager = PointsDataManager.getInstance(); + } + + IPointNode targetNode; + + int location; + + @Override + public void drop(DropTargetEvent event) { + location = determineLocation(event); + targetNode = (IPointNode) determineTarget(event); + super.drop(event); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object) + */ + @Override + public boolean performDrop(Object data) { + if (data instanceof Point[]) { + Point[] points = (Point[]) data; + if (targetNode != null) { + boolean state = false; + try { + for (Point node : points) { + IPointNode destGroup = null; + if (location == LOCATION_ON) { + if (targetNode.isGroup()) { + destGroup = targetNode; + } else { + destGroup = manager.getParent(targetNode); + } + } else if (location != LOCATION_NONE) { + destGroup = manager.getParent(targetNode); + } + if (destGroup != null + && (manager.getParent(node) + .compareTo(destGroup) != 0) + && !childGroupExists(destGroup, node.getName())) { + state = true; + dialog.setCursorBusy(true); + dialog.selectedNode = node; + manager.moveNode(node, destGroup); + } + } + return state; + } finally { + targetNode = null; + } + } + } + return false; + } + + /** + * Determine if a child of a group node is a group node with the desired + * name. + * + * @param parent + * @param name + * @return true if child group node exists. + */ + private boolean childGroupExists(IPointNode parent, String name) { + for (IPointNode child : manager.getChildren(parent, true)) { + if (child.isGroup() && name.equals(child.getName())) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object + * , int, org.eclipse.swt.dnd.TransferData) + */ + @Override + public boolean validateDrop(Object target, int operation, + TransferData transferType) { + return PointTransfer.getInstance().isSupportedType(transferType); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeLabelProvider.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeLabelProvider.java new file mode 100644 index 0000000000..d75a8a7349 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeLabelProvider.java @@ -0,0 +1,332 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.ui.dialog; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.viewers.IFontProvider; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ILabelProviderListener; +import org.eclipse.jface.viewers.ITableLabelProvider; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.viz.points.Activator; +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.ui.dialog.TriStateCellEditor.STATE; + +/** + * Provides the label for a point node. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointTreeLabelProvider implements ITableLabelProvider, + ILabelProvider, IFontProvider { + + private static final int TREE_COL_INDEX = 0; + + private static final int MOVABLE_COL_INDEX = 1; + + private static final int HIDDEN_COL_INDEX = 2; + + private static final String GROUP = "group"; + + private static final String POINT = "point"; + + private List listeners; + + private Font boldFont; + + private Color imageBackground; + + IPointNode prevPoint = null; + + private ImageRegistry imageReg; + + Shell shell; + + public PointTreeLabelProvider() { + listeners = new ArrayList(); + shell = Display.getCurrent().getActiveShell(); + + // The FontRegistry will dispose of the font. + boldFont = JFaceResources.getFontRegistry().getBold( + JFaceResources.getDefaultFont().toString()); + imageReg = new ImageRegistry(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse. + * jface.viewers.ILabelProviderListener) + */ + @Override + public void addListener(ILabelProviderListener listener) { + listeners.add(listener); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang + * .Object, java.lang.String) + */ + @Override + public boolean isLabelProperty(Object element, String property) { + return false; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse + * .jface.viewers.ILabelProviderListener) + */ + @Override + public void removeListener(ILabelProviderListener listener) { + listeners.remove(listener); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang + * .Object, int) + */ + public Image getColumnImage(Object element, int columnIndex) { + if (Activator.getDefault() == null) { + return null; + } + Image image = null; + Object key = null; + IPointNode node = (IPointNode) element; + + switch (columnIndex) { + case TREE_COL_INDEX: + if (node.isGroup()) { + key = GROUP; + } else { + key = POINT; + } + break; + case MOVABLE_COL_INDEX: + switch (node.getMovable()) { + case TRUE: + key = STATE.SELECTED; + break; + case FALSE: + key = STATE.UNSELECTED; + ; + break; + case UNKNOWN: + key = STATE.GRAYED; + ; + break; + default: + Assert.isTrue(false); + } + break; + case HIDDEN_COL_INDEX: + switch (node.getHidden()) { + case TRUE: + key = STATE.SELECTED; + break; + case FALSE: + key = STATE.UNSELECTED; + ; + break; + case UNKNOWN: + key = STATE.GRAYED; + break; + default: + Assert.isTrue(false); + } + break; + } + + if (key != null) { + if (imageReg.getDescriptor(key.toString()) != null) { + image = imageReg.get(key.toString()); + } else { + image = createImage(key); + if (image != null) { + imageReg.put(key.toString(), image); + } + } + } + return image; + } + + private Image createImage(Object key) { + Image image = null; + if (key instanceof STATE) { + image = makeImage((STATE) key); + } else { + image = PointUtils.getImage(key.toString()); + } + return image; + } + + private Image makeImage(STATE state) { + Shell s = new Shell(shell, SWT.NO_TRIM); + Button b = new Button(s, SWT.CHECK); + Point bsize = b.computeSize(SWT.DEFAULT, SWT.DEFAULT); + b.setSize(bsize); + b.setLocation(0, 0); + s.setSize(bsize); + b.setBackground(imageBackground); + switch (state) { + case SELECTED: + b.setSelection(true); + b.setGrayed(false); + break; + case UNSELECTED: + b.setSelection(false); + b.setGrayed(false); + break; + case GRAYED: + b.setSelection(true); + b.setGrayed(true); + break; + default: + Assert.isTrue(false); + } + s.open(); + + GC gc = new GC(b); + Image image = new Image(shell.getDisplay(), bsize.x, bsize.y); + gc.copyArea(image, 0, 0); + gc.dispose(); + s.close(); + return image; + } + + public void setImageBackground(Color color) { + imageBackground = color; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang + * .Object, int) + */ + public String getColumnText(Object element, int columnIndex) { + IPointNode node = (IPointNode) element; + String text = null; + if (columnIndex == TREE_COL_INDEX) { + text = node.getName(); + } + return text; + } + + /** + * @param element + * @param columnIndex + * @return + */ + public Color getForeground(Object element, int columnIndex) { + return null; + } + + /** + * @param element + * @param columnIndex + * @return + */ + public Color getBackground(Object element, int columnIndex) { + return null; + } + + /** + * @param element + * @param columnIndex + * @return + */ + public Font getFont(Object element, int columnIndex) { + IPointNode node = (IPointNode) element; + if (node.isGroup()) { + return boldFont; + } + return null; + } + + @Override + public Font getFont(Object element) { + IPointNode node = (IPointNode) element; + if (node.isGroup()) { + return boldFont; + } + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object) + */ + @Override + public Image getImage(Object element) { + return getColumnImage(element, 0); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object) + */ + @Override + public String getText(Object element) { + return getColumnText(element, 0); + } + + @Override + public void dispose() { + imageReg.dispose(); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeViewerSorter.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeViewerSorter.java new file mode 100644 index 0000000000..c1a816c830 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointTreeViewerSorter.java @@ -0,0 +1,74 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; + +import com.raytheon.uf.viz.points.data.IPointNode; + +/** + * Sort point nodes placing group nodes at the top of the list. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class PointTreeViewerSorter extends ViewerSorter { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + if (e1 == e2) { + return 0; + } + IPointNode node1 = (IPointNode) e1; + IPointNode node2 = (IPointNode) e2; + if (node1.isGroup()) { + if (!node2.isGroup()) { + return -1; + } + } else if (node2.isGroup()) { + return 1; + } + + String s1 = null; + String s2 = null; + + if (node1.isGroup()) { + s1 = node1.getGroup(); + s2 = node2.getGroup(); + } else { + s1 = node1.getName(); + s2 = node2.getName(); + } + + // Both are either points or groups + return s1.compareToIgnoreCase(s2); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointUtils.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointUtils.java new file mode 100644 index 0000000000..925e223019 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointUtils.java @@ -0,0 +1,58 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.ui.dialog; + +import java.io.File; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.swt.graphics.Image; + +import com.raytheon.uf.viz.core.icon.IconUtil; +import com.raytheon.uf.viz.points.Activator; + +/** + * List of useful static methods to support the point dialogs. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2012 #875       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class PointUtils { + public static Image getImage(String name) { + Image image = null; + StringBuilder sb = new StringBuilder("icons"); + sb.append(File.separator).append(name).append(".gif"); + ImageDescriptor imageDescriptor = IconUtil.getImageDescriptor(Activator + .getDefault().getBundle(), sb.toString()); + if (imageDescriptor != null) { + image = imageDescriptor.createImage(); + } + return image; + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointsMgrDialog.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointsMgrDialog.java new file mode 100644 index 0000000000..bfc29da6a7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/PointsMgrDialog.java @@ -0,0 +1,714 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.ui.dialog; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IMenuListener; +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ILabelDecorator; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.TreeViewerColumn; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.TreeEditor; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +import org.eclipse.swt.graphics.Rectangle; +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.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; +import org.eclipse.ui.PlatformUI; + +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.uf.viz.points.IPointChangedListener; +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.points.data.GroupNode; +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointTransfer; +import com.raytheon.uf.viz.points.ui.layer.PointsToolLayer; +import com.raytheon.viz.ui.dialogs.CaveJFACEDialog; +import com.raytheon.viz.ui.dialogs.ICloseCallback; + +/** + * Dialog to manage points and point groups. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * October-2010              epolster    Initial Creation. 
+ * Jul 31, 2012 #875       rferrel     Integrated into CAVE.
+ * Oct  2, 2012 #1234      rferrel     Clicking on new group/point when no
+ *                                      node selected will now add the new
+ *                                      to the root node.
+ * 
+ * 
+ * + * @author epolster + * @version 1.0 + */ +public class PointsMgrDialog extends CaveJFACEDialog implements + IPointChangedListener { + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(PointsMgrDialog.class); + + private static Rectangle DIALOG_BOUNDS = null; + + private static final int INITIAL_HEIGHT = 450; + + private static final int NEW_GROUP_ID = IDialogConstants.CLIENT_ID + 4; + + private static final int DELETE_POINT_ID = IDialogConstants.CLIENT_ID + 3; + + private static final int EDIT_POINT_ID = IDialogConstants.CLIENT_ID + 2; + + private static final int NEW_POINT_ID = IDialogConstants.CLIENT_ID + 1; + + Composite rootDialogArea; + + Composite mainDialogPanel; + + GridData dialogGridData; + + TableColumnLayout tableColumnLayout; + + TableViewerColumn pointNameTableViewerColumn; + + TableColumn pointNameTableColumn; + + TableViewerColumn pointMovableTableViewerColumn; + + TableColumn pointMovableTableColumn; + + TableViewerColumn pointHiddenTableViewerColumn; + + TableColumn pointHiddenTableColumn; + + Button newButton; + + Button newGroupButton; + + Button editButton; + + Button deleteButton; + + Button closeButton; + + PointsToolLayer toolLayer; + + private Shell currShell; + + protected TreeViewer pointsTreeViewer; + + private IPointNode topLevel; + + private PointsDataManager dataManager; + + private TreeEditor treeEditor; + + private Action createGroupAction; + + private Action createPointAction; + + private Action editNodeAction; + + private Action deleteNodeAction; + + protected IPointNode selectedNode = null; + + private boolean editSelectedNode = false; + + /** + * Create the dialog. + * + * @param parentShell + */ + public PointsMgrDialog(Shell parentShell, PointsToolLayer layer) { + super(parentShell); + dataManager = PointsDataManager.getInstance(); + setShellStyle(SWT.SHELL_TRIM); + toolLayer = layer; + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets + * .Shell) + */ + @Override + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + currShell = newShell; + newShell.setText("Points List"); + if (PointsMgrDialog.DIALOG_BOUNDS != null) { + newShell.setBounds(PointsMgrDialog.DIALOG_BOUNDS); + } + } + + /** + * Create contents of the dialog. + * + * @param parent + */ + @Override + protected Control createDialogArea(Composite parent) { + rootDialogArea = (Composite) super.createDialogArea(parent); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + rootDialogArea.setLayoutData(gd); + + mainDialogPanel = new Composite(rootDialogArea, SWT.NONE); + dialogGridData = new GridData(SWT.LEFT, SWT.CENTER, true, true, 1, 1); + dialogGridData.heightHint = 193; + dialogGridData.widthHint = 422; + mainDialogPanel.setLayoutData(dialogGridData); + mainDialogPanel.setLayout(new GridLayout(1, true)); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + mainDialogPanel.setLayoutData(gd); + + Composite tc = new Composite(mainDialogPanel, SWT.NONE); + tc.setLayout(new GridLayout(1, false)); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + tc.setLayoutData(gd); + pointsTreeViewer = new TreeViewer(tc, SWT.BORDER | SWT.V_SCROLL + | SWT.H_SCROLL | SWT.FULL_SELECTION); + Tree tree = pointsTreeViewer.getTree(); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + tree.setLayoutData(gd); + + tree.setHeaderVisible(true); + TreeViewerColumn tvc = new TreeViewerColumn(pointsTreeViewer, SWT.LEFT, + 0); + TreeColumn column = tvc.getColumn(); + column.setWidth(300); + column.setText("Point Name"); + tvc = new TreeViewerColumn(pointsTreeViewer, SWT.LEFT, 1); + column = tvc.getColumn(); + column.setWidth(80); + column.setText("Movable"); + tvc.setEditingSupport(new PointMovableEditingSupport(pointsTreeViewer, + toolLayer)); + + tvc = new TreeViewerColumn(pointsTreeViewer, SWT.LEFT | SWT.CHECK, 2); + column = tvc.getColumn(); + column.setWidth(80); + column.setText("Hidden"); + tvc.setEditingSupport(new PointHiddenEditingSupport(pointsTreeViewer, + toolLayer)); + + pointsTreeViewer.setContentProvider(new PointTreeContentProvider()); + ILabelDecorator decorator = PlatformUI.getWorkbench() + .getDecoratorManager().getLabelDecorator(); + PointTreeLabelProvider labelProvider = new PointTreeLabelProvider(); + labelProvider.setImageBackground(pointsTreeViewer.getTree() + .getBackground()); + pointsTreeViewer.setLabelProvider(new PointDecoratingLabelProvider( + labelProvider, decorator)); + pointsTreeViewer.setSorter(new PointTreeViewerSorter()); + loadTreeInput(); + pointsTreeViewer.setInput(topLevel); + pointsTreeViewer.refresh(); + + treeEditor = new TreeEditor(pointsTreeViewer.getTree()); + treeEditor.horizontalAlignment = SWT.LEFT; + treeEditor.grabHorizontal = true; + treeEditor.minimumWidth = 50; + + createGroupAction = new Action() { + @Override + public void run() { + createGroup(); + } + }; + createGroupAction.setText("New Group"); + + createPointAction = new Action() { + @Override + public void run() { + createPoint(); + } + }; + createPointAction.setText("New Point..."); + + editNodeAction = new Action() { + @Override + public void run() { + editNode(); + } + }; + editNodeAction.setText("Edit..."); + + deleteNodeAction = new Action() { + @Override + public void run() { + deleteNode(); + } + }; + deleteNodeAction.setText("Delete"); + + MenuManager menuMgr = new MenuManager(); + Menu menu = menuMgr.createContextMenu(pointsTreeViewer.getControl()); + menuMgr.add(createGroupAction); + menuMgr.add(createPointAction); + menuMgr.add(editNodeAction); + menuMgr.add(deleteNodeAction); + + menuMgr.addMenuListener(new IMenuListener() { + + @Override + public void menuAboutToShow(IMenuManager manager) { + // TODO only add action if mouse is hovering over a row instead + // of an empty area. + manager.add(createGroupAction); + manager.add(createPointAction); + manager.add(editNodeAction); + manager.add(deleteNodeAction); + } + }); + + menuMgr.setRemoveAllWhenShown(true); + pointsTreeViewer.getControl().setMenu(menu); + + int operations = DND.DROP_COPY | DND.DROP_MOVE; + Transfer[] transferTypes = new Transfer[] { PointTransfer.getInstance() }; + pointsTreeViewer.addDragSupport(operations, transferTypes, + new PointTreeDragSourceListener(pointsTreeViewer)); + + pointsTreeViewer.addDropSupport(operations, transferTypes, + new PointTreeDropListener(this)); + return rootDialogArea; + } + + private Point[] getTableInput() { + Collection points = dataManager.getPoints(); + Iterator iter = points.iterator(); + Point[] pointsArray = new Point[points.size()]; + for (int i = 0; i < points.size(); i++) { + pointsArray[i] = iter.next(); + } + return pointsArray; + } + + private void loadTreeInput() { + topLevel = dataManager.getPoint(""); + } + + public void refreshFromModel() { + + if (pointsTreeViewer != null && getShell() != null + && getShell().getDisplay() != null + && !getShell().getDisplay().isDisposed()) { + loadTreeInput(); + getShell().getDisplay().syncExec(new Runnable() { + public void run() { + pointsTreeViewer.setInput(getTableInput()); + } + }); + } + } + + /** + * Create contents of the button bar. + * + * @param parent + */ + @Override + protected void createButtonsForButtonBar(final Composite parent) { + newGroupButton = createButton(parent, NEW_GROUP_ID, "New Group", false); + newGroupButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + createGroup(); + } + }); + + newButton = createButton(parent, NEW_POINT_ID, "New Point...", false); + newButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + createPoint(); + } + }); + + editButton = createButton(parent, EDIT_POINT_ID, "Edit...", false); + editButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + editNode(); + } + }); + + deleteButton = createButton(parent, DELETE_POINT_ID, "Delete", false); + deleteButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + deleteNode(); + } + + }); + + closeButton = createButton(parent, IDialogConstants.CLOSE_ID, + IDialogConstants.CLOSE_LABEL, false); + closeButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + }); + } + + private void createGroup() { + IPointNode parentNode = null; + + selectedNode = getSelectedPoint(); + if (selectedNode == null) { + parentNode = dataManager.getPoint(""); + } else { + parentNode = dataManager.getParent(selectedNode); + } + + try { + setCursorBusy(true); + editSelectedNode = true; + selectedNode = dataManager.createTempGroup(parentNode); + } catch (LocalizationOpFailedException e1) { + statusHandler.handle( + Priority.PROBLEM, + "Unable to create a temporary group under: " + + parentNode.getName()); + return; + } + } + + private void createPoint() { + Point point = getSelectedPoint(); + if (point == null) { + point = dataManager.getPoint(""); + } + if (point != null) { + ICloseCallback cb = new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof Point) { + Point newPoint = (Point) returnValue; + setCursorBusy(true); + selectedNode = newPoint; + toolLayer.addPoint(newPoint); + } + } + }; + PointEditDialog.createNewPointViaDialog(toolLayer, point, cb); + } + } + + private TreeItem findItem(IPointNode point, TreeItem[] items) { + TreeItem item = null; + ViewerComparator vc = pointsTreeViewer.getComparator(); + for (TreeItem it : items) { + IPointNode itPoint = (IPointNode) it.getData(); + if (itPoint != null) { + if (vc.compare(pointsTreeViewer, point, itPoint) == 0) { + item = it; + break; + } else if (it.getItemCount() > 0) { + item = findItem(point, it.getItems()); + if (item != null) { + break; + } + } + } + } + return item; + } + + private void editNode() { + final Point point = getSelectedPoint(); + if (point != null) { + if (point.isGroup()) { + editGroupName(); + } else { + setCursorBusy(true); + ICloseCallback cb = new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof Point) { + if (returnValue instanceof Point) { + Point em = (Point) returnValue; + dataManager.updatePoint(point, em); + } + } else { + setCursorBusy(false); + } + } + }; + PointEditDialog.editPointViaDialog(toolLayer, point, cb); + } + } else { + MessageDialog.openInformation(getShell(), "Message", + "Please select a point to edit."); + } + } + + private void deleteNode() { + Point point = getSelectedPoint(); + if (point != null) { + setCursorBusy(true); + if (!toolLayer.deletePoint(point)) { + setCursorBusy(false); + } + } + } + + private void editGroupName() { + TreeSelection selection = (TreeSelection) pointsTreeViewer + .getSelection(); + Control oldEditor = treeEditor.getEditor(); + if (oldEditor != null) { + oldEditor.dispose(); + } + final IPointNode entry = (IPointNode) selection.getFirstElement(); + + final Composite comp = new Composite(pointsTreeViewer.getTree(), + SWT.NONE); + comp.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK)); + final Text text = new Text(comp, SWT.NONE); + text.addModifyListener(new ModifyListener() { + + @Override + public void modifyText(ModifyEvent e) { + Text text = (Text) treeEditor.getEditor(); + treeEditor.getItem().setText(text.getText()); + } + }); + + final TreeItem item = pointsTreeViewer.getTree().getSelection()[0]; + boolean showBorder = true; + final Composite composite = new Composite(pointsTreeViewer.getTree(), + SWT.NONE); + if (showBorder) + composite.setBackground(Display.getCurrent().getSystemColor( + SWT.COLOR_BLACK)); + final Text modText = new Text(composite, SWT.NONE); + final int inset = showBorder ? 1 : 0; + composite.addListener(SWT.Resize, new Listener() { + public void handleEvent(Event e) { + Rectangle rect = composite.getClientArea(); + modText.setBounds(rect.x + inset, rect.y + inset, rect.width + - inset * 2, rect.height - inset * 2); + } + }); + Listener textListener = new Listener() { + public void handleEvent(final Event e) { + switch (e.type) { + case SWT.KeyUp: + if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) { + // do nothing, want to go on to the focus out + } else { + break; + } + case SWT.FocusOut: + final String text = modText.getText().trim(); + if (text.length() == 0 || entry.getName().equals(text) + || groupExists(dataManager.getParent(entry), text)) { + item.setText(entry.getName()); + } else { + GroupNode node = new GroupNode((GroupNode) entry); + node.setName(text); + StringBuilder sb = new StringBuilder(node.getGroup()); + sb.setLength(sb.lastIndexOf(File.separator) + 1); + selectedNode = node; + sb.append(text); + + item.setText(text); + setCursorBusy(true); + if (!dataManager.renameGroup(entry, text)) { + setCursorBusy(false); + } + } + composite.dispose(); + break; + case SWT.Verify: + if (!e.text.matches("[0-9A-Za-z_ ]*")) { + e.doit = false; + } + + break; + default: + statusHandler.handle(Priority.PROBLEM, "Unhandled type: " + + e.type); + } + } + }; + modText.addListener(SWT.KeyUp, textListener); + modText.addListener(SWT.Verify, textListener); + modText.addListener(SWT.FocusOut, textListener); + treeEditor.setEditor(composite, item); + String tmpText = item.getText(); + modText.setText(tmpText); + modText.selectAll(); + modText.setFocus(); + } + + private boolean groupExists(IPointNode parent, String name) { + for (IPointNode child : dataManager.getChildren(parent, true)) { + if (child.isGroup() && name.equals(child.getName())) { + return true; + } + } + return false; + } + + private Point getSelectedPoint() { + TreeItem[] selItems = pointsTreeViewer.getTree().getSelection(); + Point point = null; + if (selItems.length > 0) { + point = (Point) selItems[0].getData(); + } + return point; + } + + protected void setCursorBusy(boolean state) { + Cursor cursor = null; + if (state) { + cursor = getShell().getDisplay().getSystemCursor(SWT.CURSOR_WAIT); + } + getShell().setCursor(cursor); + pointsTreeViewer.getTree().setCursor(cursor); + } + + @Override + public boolean close() { + dataManager.removePointsChangedListener(this); + DIALOG_BOUNDS = currShell.getBounds(); + return super.close(); + } + + @Override + public int open() { + dataManager.addPointsChangedListener(this); + return super.open(); + } + + @Override + public void pointChanged() { + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + if (selectedNode == null) { + selectedNode = getSelectedPoint(); + } + + // Bug in viewers refresh that causes stack overflow when + // selected item no longer exists and sometimes when the + // selected item was modified. + pointsTreeViewer.setSelection(null); + pointsTreeViewer.refresh(topLevel); + + if (selectedNode != null) { + Tree tree = pointsTreeViewer.getTree(); + TreeItem item = findItem(selectedNode, tree.getItems()); + if (item != null) { + tree.showItem(item); + tree.select(item); + if (editSelectedNode) { + editNode(); + editSelectedNode = false; + } + } + selectedNode = null; + } + setCursorBusy(false); + } + }); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.dialogs.Dialog#getInitialSize() + */ + @Override + protected org.eclipse.swt.graphics.Point getInitialSize() { + if (DIALOG_BOUNDS == null) { + org.eclipse.swt.graphics.Point pt = super.getInitialSize(); + if (pt.y < INITIAL_HEIGHT) { + pt.y = INITIAL_HEIGHT; + } + return pt; + } + return new org.eclipse.swt.graphics.Point(DIALOG_BOUNDS.width, + DIALOG_BOUNDS.height); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.dialogs.Dialog#getInitialLocation(org.eclipse.swt.graphics + * .Point) + */ + @Override + protected org.eclipse.swt.graphics.Point getInitialLocation( + org.eclipse.swt.graphics.Point initialSize) { + if (DIALOG_BOUNDS == null) { + return super.getInitialLocation(initialSize); + } + return new org.eclipse.swt.graphics.Point(DIALOG_BOUNDS.x, + DIALOG_BOUNDS.y); + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/TriStateCellEditor.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/TriStateCellEditor.java new file mode 100644 index 0000000000..63c6809765 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/dialog/TriStateCellEditor.java @@ -0,0 +1,170 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.points.ui.dialog; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.viewers.CellEditor; +import org.eclipse.jface.viewers.ColumnViewerEditorActivationEvent; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * A cell editor that manages a tri-state checkbox. The cell editor's value is + * one of the STATE enum values. + *

+ * This class may be instantiated; it is not intended to be subclassed. + *

+ *

+ * Note that this implementation simply fakes it and does does not create any + * new controls. The mere activation of this editor means that the value of the + * check box is being toggled by the end users; the listener method + * applyEditorValue is immediately called to signal the change. + *

+ * + * @noextend This class is not intended to be subclassed by clients. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Sep 13, 2012            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class TriStateCellEditor extends CellEditor { + public static enum STATE { + GRAYED, SELECTED, UNSELECTED + }; + + /** + * Default CheckboxCellEditor style + */ + private static final int defaultStyle = SWT.NONE; + + /** + * The cell value. + */ + private STATE value = STATE.GRAYED; + + /** + * Creates a new cell editor with no control + */ + public TriStateCellEditor() { + setStyle(defaultStyle); + } + + /** + * Creates a new cell editor parented under the given control. The cell + * editor value is a STATE value, which is initially GRAYED. + * Initially, the cell editor has no cell validator. + * + * @param parent + * the parent control + */ + public TriStateCellEditor(Composite parent) { + this(parent, defaultStyle); + } + + /** + * Creates a new cell editor parented under the given control. The cell + * editor value is a STATE value, which is initially GRAYED. + * Initially, the cell editor has no cell validator. + * + * @param parent + * the parent control + * @param style + * the style bits + */ + public TriStateCellEditor(Composite parent, int style) { + super(parent, style); + } + + /** + * The TriStateCellEditor implementation of this + * CellEditor framework method simulates the toggling of the + * checkbox control and notifies listeners with + * ICellEditorListener.applyEditorValue. + */ + public void activate() { + if (value == STATE.SELECTED) { + value = STATE.UNSELECTED; + } else { + // Change either GRAYED or UNSELECTED + value = STATE.SELECTED; + } + fireApplyEditorValue(); + } + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.jface.viewers.CellEditor#createControl(org.eclipse.swt.widgets + * .Composite) + */ + @Override + protected Control createControl(Composite parent) { + return null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.CellEditor#doGetValue() + */ + @Override + protected Object doGetValue() { + return value; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.CellEditor#doSetFocus() + */ + @Override + protected void doSetFocus() { + // Ignore + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.jface.viewers.CellEditor#doSetValue(java.lang.Object) + */ + @Override + protected void doSetValue(Object value) { + Assert.isTrue(value instanceof STATE); + this.value = (STATE) value; + } + + public void activate(ColumnViewerEditorActivationEvent activationEvent) { + if (activationEvent.eventType != ColumnViewerEditorActivationEvent.TRAVERSAL) { + super.activate(activationEvent); + } + } +} diff --git a/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/layer/PointsToolLayer.java b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/layer/PointsToolLayer.java new file mode 100644 index 0000000000..b69324b505 --- /dev/null +++ b/cave/com.raytheon.uf.viz.points/src/com/raytheon/uf/viz/points/ui/layer/PointsToolLayer.java @@ -0,0 +1,478 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ + +package com.raytheon.uf.viz.points.ui.layer; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.jface.action.IMenuManager; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.widgets.MessageBox; +import org.opengis.referencing.FactoryException; +import org.opengis.referencing.operation.TransformException; + +import com.raytheon.uf.common.geospatial.ReferencedCoordinate; +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IDisplayPaneContainer; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.core.rsc.IResourceDataChanged; +import com.raytheon.uf.viz.core.rsc.LoadProperties; +import com.raytheon.uf.viz.core.rsc.capabilities.ColorableCapability; +import com.raytheon.uf.viz.core.rsc.capabilities.MagnificationCapability; +import com.raytheon.uf.viz.core.rsc.tools.AbstractMovableToolLayer; +import com.raytheon.uf.viz.core.rsc.tools.AwipsToolsResourceData; +import com.raytheon.uf.viz.points.IPointChangedListener; +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.points.data.IPointNode; +import com.raytheon.uf.viz.points.data.Point; +import com.raytheon.uf.viz.points.data.PointFieldState; +import com.raytheon.uf.viz.points.data.PointNameChangeException; +import com.raytheon.uf.viz.points.ui.dialog.PointEditDialog; +import com.raytheon.viz.ui.cmenu.AbstractRightClickAction; +import com.raytheon.viz.ui.cmenu.IContextMenuContributor; +import com.raytheon.viz.ui.dialogs.ICloseCallback; +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.GeometryFactory; + +/** + * Implements the points bearing functionality. + * + * + *
+ * 
+ *  SOFTWARE HISTORY
+ * 
+ *  Date         Ticket#     Engineer    Description
+ *  ------------ ----------  ----------- --------------------------
+ *  Oct032007    #463        ebabin      Initial Creation.
+ *  26Oct2007    #504        ebabin      Update to use BaselineLoader class.
+ *  02Sept2008   #1516       dhladky     de-JIBX baselines.
+ *  14Oct2009    #810        bsteffen    Fix for grabbing points.
+ *  10-21-09     #1711       bsteffen    Refactor to common MovableTool model
+ *  05-27-10     #5362       bkowal      When NULL Is Passed To The 'move'
+ *                                       Function As The Last Coordinate,
+ *                                       The Current Coordinates Of The Point
+ *                                       Passed To The Function Are Used.
+ *                                       Constructor Now Sets The
+ *                                       'rightClickMovesToCoord' Indicator
+ *                                       Owned By The Super Class.
+ *  02-08-11     #8214       bkowal      Points now have the Magnification
+ *                                       capability.
+ *  07-31-2012   #875        rferrel     Converted to use points.
+ * 
+ * 
+ * + * @author ebabin + * @version 1 + */ +public class PointsToolLayer extends AbstractMovableToolLayer implements + IContextMenuContributor, IPointChangedListener, IResourceDataChanged { + + public static final String DEFAULT_NAME = "Interactive Points"; + + private AbstractRightClickAction deleteElementAction; + + private AbstractRightClickAction editElementAction; + + private AbstractRightClickAction hideElementAction; + + private AbstractRightClickAction moveElementAction; + + private AbstractRightClickAction createElementAction; + + private PointsDataManager dataManager; + + private static GeometryFactory gf = new GeometryFactory(); + + Map fonts; + + public PointsToolLayer( + AwipsToolsResourceData resourceData, + LoadProperties loadProperties) { + super(resourceData, loadProperties); + this.dataManager = PointsDataManager.getInstance(); + deleteElementAction = new AbstractRightClickAction() { + @Override + public void run() { + deletePoint(selectedObject); + } + }; + deleteElementAction.setText("Delete Point"); + + editElementAction = new AbstractRightClickAction() { + @Override + public void run() { + editPoint(selectedObject); + } + }; + editElementAction.setText("Edit Point..."); + + hideElementAction = new AbstractRightClickAction() { + @Override + public void run() { + hidePoint(selectedObject); + } + }; + hideElementAction.setText("Hide Point"); + + moveElementAction = new AbstractRightClickAction() { + @Override + public void run() { + makeSelectedLive(); + } + }; + moveElementAction.setText("Move Point"); + + createElementAction = new AbstractRightClickAction() { + @Override + public void run() { + createPoint(); + } + }; + createElementAction.setText("New Point..."); + + this.rightClickMovesToCoord = true; + this.resourceData.addChangeListener(this); + this.fonts = new HashMap(); + } + + @Override + protected void disposeInternal() { + super.disposeInternal(); + dataManager.removePointsChangedListener(this); + for (IFont font : fonts.values()) { + font.dispose(); + } + this.resourceData.removeChangeListener(this); + } + + @Override + protected void initInternal(IGraphicsTarget target) throws VizException { + super.initInternal(target); + resetPoints(); + dataManager.addPointsChangedListener(this); + } + + private void resetPoints() { + Object selectedLabel = null; + if (selectedObject != null) { + selectedLabel = selectedObject.getName(); + } + Point selectedPoint = null; + Collection points = new ArrayList(); + for (String name : dataManager.getVisiblePointNames()) { + Point point = dataManager.getPoint(name); + points.add(point); + if (name.equals(selectedLabel)) { + selectedPoint = point; + } + } + setObjects(points); + selectedObject = selectedPoint; + } + + @Override + protected void paint(IGraphicsTarget target, PaintProperties paintProps, + Point point, SelectionStatus status) throws VizException { + + RGB color = point.getColor(); + if (status == SelectionStatus.SELECTED) { + color = GRAY; + } else if (color == null || !point.isColorActive()) { + color = getCapability(ColorableCapability.class).getColor(); + } + + double radius = (MAGIC_CIRCLE_RADIUS * paintProps.getZoomLevel()); + String label = point.getName(); + Coordinate coordinate = point.getCoordinate(); + double[] center = descriptor.worldToPixel(new double[] { coordinate.x, + coordinate.y }); + + // Outer unfilled circle + DrawableCircle dc = new DrawableCircle(); + dc.basics.x = center[0]; + dc.basics.y = center[1]; + dc.radius = radius; + dc.basics.color = color; + dc.lineWidth = 1; + + // Inner filled circle + DrawableCircle dfc = new DrawableCircle(); + dfc.basics.x = center[0]; + dfc.basics.y = center[1]; + dfc.radius = radius / 2; + dfc.basics.color = color; + dfc.lineWidth = 1; + dfc.filled = true; + + // draw circles + target.drawCircle(dc, dfc); + + double labelLoc[] = target.getPointOnCircle(center[0], center[1], 0.0, + radius, 0); + + int fontSize = point.getFontSize().getFontSize(); + Double magnification = getCapability(MagnificationCapability.class) + .getMagnification(); + + Integer fontKey = fontSize; + IFont font = fonts.get(fontKey); + + if (font == null) { + font = target.getDefaultFont().deriveWithSize( + (float) (fontSize * magnification)); + fonts.put(fontKey, font); + } + + DrawableString parameters = new DrawableString(label, color); + parameters.font = font; + parameters.setCoordinates(labelLoc[0], labelLoc[1]); + target.drawStrings(parameters); + } + + @Override + public String getDefaultName() { + return DEFAULT_NAME; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.cmenu.IContextMenuContributor#addContextMenuItems + * (org.eclipse.jface.action.IMenuManager, int, int) + */ + @Override + public void addContextMenuItems(IMenuManager menuManager, int x, int y) { + if (isEditable()) { + selectedObject = null; + selectObjectAtMouse(x, y, -1); + if (selectedObject != null) { + menuManager.add(editElementAction); + menuManager.add(hideElementAction); + menuManager.add(deleteElementAction); + if (selectedObject.getMovable() == PointFieldState.TRUE) { + menuManager.add(moveElementAction); + } + } else { + menuManager.add(createElementAction); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.rsc.AbstractVizResource#inspect(com.raytheon + * .uf.common.geospatial.ReferencedCoordinate) + */ + @Override + public String inspect(ReferencedCoordinate coord) throws VizException { + if (isEditable()) { + Coordinate point = null; + IDisplayPaneContainer container = getResourceContainer(); + try { + double[] pixelLoc = container.translateInverseClick(coord + .asLatLon()); + point = new Coordinate(pixelLoc[0], pixelLoc[1]); + } catch (TransformException e) { + throw new VizException(e.getMessage()); + } catch (FactoryException e) { + throw new VizException(e.getMessage()); + } + for (Point object : objects) { + if (isClicked(getResourceContainer(), point, object)) { + return object.getName() + " Movable: " + + object.getMovable().toString().toLowerCase(); + } + } + } + return null; + } + + @Override + public void pointChanged() { + resetPoints(); + issueRefresh(); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.awipstools.ui.layer.AbstractMovableToolLayer#isClicked + * (com.raytheon.uf.viz.core.IDisplayPaneContainer, + * com.vividsolutions.jts.geom.Coordinate, java.lang.Object) + */ + @Override + protected boolean isClicked(IDisplayPaneContainer container, + Coordinate mouseLoc, Point point) { + endpointClicked = false; + double[] pixelLoc = container.translateInverseClick(point + .getCoordinate()); + com.vividsolutions.jts.geom.Point pixelPoint = gf + .createPoint(new Coordinate(pixelLoc[0], pixelLoc[1])); + com.vividsolutions.jts.geom.Point clickPoint = gf.createPoint(mouseLoc); + if (pixelPoint.isWithinDistance(clickPoint, MAGIC_CLICK_DISTANCE)) { + endpointClicked = true; + return true; + } + return false; + + } + + @Override + protected Point makeLive(Point object) { + return new Point(object); + } + + @Override + protected Point move(Coordinate lastClickedCoordinate, Coordinate clickLoc, + Point point) { + if (point.getMovable() == PointFieldState.TRUE) { + if (clickLoc == null) { + clickLoc = lastClickedCoordinate; + // Get The Current Coordinates Of The "Point". + lastClickedCoordinate = this.dataManager.getCoordinate(point + .getName()); + } + + Point newPoint = new Point(point); + newPoint.setCoordinate(clickLoc); + return newPoint; + } + return point; + } + + @Override + protected void save(Point oldPoint, Point point) { + String label = point.getName(); + dataManager.setCoordinate(label, point.getCoordinate()); + resourceData.fireChangeListeners(ChangeType.DATA_UPDATE, null); + } + + @Override + public void resourceChanged(ChangeType type, Object object) { + if (type == ChangeType.CAPABILITY) { + if (object instanceof MagnificationCapability) { + for (IFont font : fonts.values()) { + font.dispose(); + } + fonts.clear(); + } + } + this.issueRefresh(); + } + + public void addPoint(Point point) { + if (point != null) { + dataManager.addPoint(point); + } + } + + public void hidePoint(Point point) { + if (point != null) { + point.setHidden(PointFieldState.TRUE); + dataManager.addPoint(point); + } + } + + public boolean deletePoint(Point point) { + boolean state = false; + if (point != null) { + MessageBox d = new MessageBox(getResourceContainer() + .getActiveDisplayPane().getDisplay().getActiveShell(), + SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL); + if (point.isGroup()) { + d.setMessage("Click OK to delete the group:\n" + + point.getGroup() + + "\nand all points and sub-groups\nit contains."); + } else { + d.setMessage("Click OK to delete point " + point.getName() + + "?"); + } + int status = d.open(); + if (status == SWT.OK) { + state = true; + dataManager.deletePoint(point); + } + } + return state; + } + + private void editPoint(final Point point) { + ICloseCallback cb = new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof Point) { + Point em = (Point) returnValue; + dataManager.updatePoint(point, em); + } + } + }; + PointEditDialog.editPointViaDialog(this, point, cb); + } + + private void createPoint() { + Point point = new Point("", lastMouseLoc.y, lastMouseLoc.x, + PointFieldState.FALSE, PointFieldState.TRUE, false, new RGB(0, + 0, 0), ""); + ICloseCallback cb = new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof Point) { + Point em = (Point) returnValue; + dataManager.addPoint(em); + } + } + }; + PointEditDialog.createNewPointViaDialog(this, point, cb); + } + + /** + * This is used to change everything on the point except for its unique + * name. This throws an exception if the point does not exist. + * + * @param point + * @throws PointNameChangeException + */ + public void updatePoint(Point point) throws PointNameChangeException { + dataManager.updatePoint(point); + } + + public void updateChildrenHidden(IPointNode node, PointFieldState state) { + dataManager.updateChildrenHidden(node, state); + } + + public void updateChildrenMovable(IPointNode node, PointFieldState state) { + dataManager.updateChildrenMovable(node, state); + } +} diff --git a/cave/com.raytheon.uf.viz.radar.gl/src/com/raytheon/uf/viz/radar/gl/RadarRadialMesh.java b/cave/com.raytheon.uf.viz.radar.gl/src/com/raytheon/uf/viz/radar/gl/RadarRadialMesh.java index 9872d18713..b5bdb86163 100644 --- a/cave/com.raytheon.uf.viz.radar.gl/src/com/raytheon/uf/viz/radar/gl/RadarRadialMesh.java +++ b/cave/com.raytheon.uf.viz.radar.gl/src/com/raytheon/uf/viz/radar/gl/RadarRadialMesh.java @@ -48,7 +48,7 @@ import com.raytheon.viz.core.gl.SharedCoordMap.SharedCoordinateKey; * * SOFTWARE HISTORY Date Ticket# Engineer Description ------------ ---------- * ----------- -------------------------- Jun 10, 2010 mschenke Initial creation - * + * OCT 09, 2012 15018 kshresth *
* * @author mschenke @@ -408,6 +408,12 @@ public class RadarRadialMesh extends AbstractGLMesh { if (jStart == null) { jStart = 0; } + + //check if numBins and numRadials equals to zero, then angleData does not exist + if (numBins == 0 && numRadials == 0 ) { + return null; + } + float[] angleData = radarData.getAngleData(); CacheKey key = new CacheKey(latitude, longitude, numBins, numRadials, gateResolution, trueElevationAngle, jStart, angleData, diff --git a/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/BaseRadarProductUI.java b/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/BaseRadarProductUI.java index 252de0d2a1..f1d0dea438 100644 --- a/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/BaseRadarProductUI.java +++ b/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/BaseRadarProductUI.java @@ -70,6 +70,8 @@ import com.raytheon.rcm.products.RadarProduct; import com.raytheon.rcm.products.RadarProduct.Param; import com.raytheon.rcm.products.Usage; import com.raytheon.rcm.request.Request; +import com.raytheon.uf.viz.points.PointsDataManager; +import com.raytheon.uf.viz.points.data.IPointNode; import com.raytheon.uf.viz.radarapps.core.RadarApps; import com.raytheon.uf.viz.radarapps.products.ui.PMenu.PMenuItem; import com.raytheon.uf.viz.radarapps.products.ui.PMenu.PProductItem; @@ -92,6 +94,7 @@ import com.raytheon.viz.ui.widgets.MinimumSizeComposite; * Jul 11, 2012 #875 rferrel Refactored for changes in MenuButton and * converted to abstract class making the * needed methods abstract. + * Jul 31, 2012 #875 rferrel Points now group in menu items. * * * @@ -130,7 +133,7 @@ public abstract class BaseRadarProductUI { private ScaleWithLabel[] azRan2; - protected Combo geomCombo; + protected Composite geomCombo; protected String desiredGeom = "A"; @@ -961,16 +964,8 @@ public abstract class BaseRadarProductUI { } if (first.params.contains(Param.WINDOW_AZ_RAN)) { - String[] points = getPointList(); - if (points != null) { - isPoints = true; - createGeom(rows, "Point:", points, "Load Points"); - } else { - r = new Composite(rows, SWT.NONE); - l = new Label(r, SWT.LEFT); - l.setText("Window center"); - azRan1 = createAzRan(l, r); - } + isPoints = true; + createGeom(rows, "Point:", null, "Load Points"); } if (first.params.contains(Param.STORM_SPEED_DIR)) { @@ -1164,12 +1159,37 @@ public abstract class BaseRadarProductUI { Label l = new Label(r2, SWT.LEFT); l.setText(labelText); - Combo c = new Combo(r2, SWT.READ_ONLY); - for (String s : list) - c.add(s); - gd = new GridData(); - gd.horizontalIndent = 20; - c.setLayoutData(gd); + if (!isPoints) { + Combo c = new Combo(r2, SWT.READ_ONLY); + for (String s : list) + c.add(s); + gd = new GridData(); + gd.horizontalIndent = 20; + c.setLayoutData(gd); + // TODO: points=true/false .. means baseline/point are exclusive + // (well, they are exclusive...) + c.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + Combo c = (Combo) e.widget; + onGeomSelected(c.getItem(c.getSelectionIndex())); + } + }); + geomCombo = c; + } else { + MenuButton mb = new MenuButton(r2); + mb.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + MenuItem item = (MenuItem) e.data; + onGeomSelected(item.getText()); + } + }); + mb.setMinimumSize(SWT.DEFAULT, SWT.DEFAULT); + + Menu menu = new Menu(mb); + createMenuItems(menu, null); + mb.setMenu(menu); + geomCombo = mb; + } azRanLabel = new Label(r2, SWT.LEFT); if (isPoints) @@ -1196,20 +1216,30 @@ public abstract class BaseRadarProductUI { }); gd = new GridData(SWT.RIGHT, SWT.CENTER, true, false); - // TODO: points=true/false .. means baseline/point are exclusive - // (well, they are exclusive...) - c.addSelectionListener(new SelectionAdapter() { - public void widgetSelected(SelectionEvent e) { - Combo c = (Combo) e.widget; - onGeomSelected(c.getItem(c.getSelectionIndex())); - } - }); - geomCombo = c; - // TODO: left side will not grab extra space... Needed for azRanLabel setupRow(r, r2, b); } + private void createMenuItems(Menu menu, IPointNode root) { + MenuItem item = null; + for (IPointNode node : PointsDataManager.getInstance().getChildren( + root)) { + if (node.isGroup()) { + if (PointsDataManager.getInstance().getChildren(node).size() == 0) { + continue; + } + Menu childMenu = new Menu(menu); + item = new MenuItem(menu, SWT.CASCADE); + item.setMenu(childMenu); + createMenuItems(childMenu, node); + } else { + item = new MenuItem(menu, SWT.PUSH); + } + item.setText(node.getName()); + item.setData(node); + } + } + protected void onLoadBaselines() { // Default implementation does nothing } @@ -1965,9 +1995,17 @@ public abstract class BaseRadarProductUI { } if (geomCombo != null) { - int index = geomCombo.indexOf(desiredGeom); - if (index != -1) - geomCombo.select(index); + if (geomCombo instanceof Combo) { + Combo c = (Combo) geomCombo; + int index = c.indexOf(desiredGeom); + if (index != -1) { + c.select(index); + } + } else { + MenuButton mb = (MenuButton) geomCombo; + mb.setSelectedItem(desiredGeom); + } + } refreshAzRanLabel(); @@ -2412,13 +2450,6 @@ public abstract class BaseRadarProductUI { */ abstract protected String[] getBaselineList(); - /** - * Get an array of point names to process. - * - * @return pointNames - */ - abstract protected String[] getPointList(); - /** * Get point's azimuth and range from the radar. * diff --git a/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/RadarProductUI.java b/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/RadarProductUI.java index 0017808efd..62fd2beb97 100644 --- a/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/RadarProductUI.java +++ b/cave/com.raytheon.uf.viz.radarapps.core/src/com/raytheon/uf/viz/radarapps/products/ui/RadarProductUI.java @@ -52,14 +52,6 @@ public class RadarProductUI extends BaseRadarProductUI { return baselineNames.toArray(new String[baselineNames.size()]); } - @Override - protected String[] getPointList() { - ArrayList pointNames = new ArrayList(PointsDataManager - .getInstance().getPointNames()); - Collections.sort(pointNames); - return pointNames.toArray(new String[pointNames.size()]); - } - @Override protected float[] getBaselineLatLon(String which) { maybeAddPrefListener(); @@ -106,7 +98,7 @@ public class RadarProductUI extends BaseRadarProductUI { @Override protected float[] getPointLatLon(String which) { maybeAddPrefListener(); - Coordinate c = PointsDataManager.getInstance().getPoint(which); + Coordinate c = PointsDataManager.getInstance().getCoordinate(which); if (c != null) { float[] result = { (float) c.y, (float) c.x }; return result; diff --git a/cave/com.raytheon.uf.viz.remote.graphics/.classpath b/cave/com.raytheon.uf.viz.remote.graphics/.classpath new file mode 100644 index 0000000000..1fa3e6803d --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/cave/com.raytheon.uf.viz.remote.graphics/.project b/cave/com.raytheon.uf.viz.remote.graphics/.project new file mode 100644 index 0000000000..e4af29ece0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/.project @@ -0,0 +1,28 @@ + + + com.raytheon.uf.viz.remote.graphics + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/cave/com.raytheon.uf.viz.remote.graphics/.settings/org.eclipse.jdt.core.prefs b/cave/com.raytheon.uf.viz.remote.graphics/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..bb4ea4f95f --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +#Mon Mar 05 15:58:59 CST 2012 +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/cave/com.raytheon.uf.viz.remote.graphics/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.remote.graphics/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..98e79b34d5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/META-INF/MANIFEST.MF @@ -0,0 +1,35 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Remote Graphics +Bundle-SymbolicName: com.raytheon.uf.viz.remote.graphics;singleton:=true +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: com.raytheon.uf.viz.remote.graphics.Activator +Bundle-Vendor: RAYTHEON +Eclipse-RegisterBuddy: com.raytheon.uf.viz.core +Eclipse-BuddyPolicy: dependent +Require-Bundle: org.eclipse.ui, + org.eclipse.core.runtime, + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + org.geotools;bundle-version="2.6.4", + com.raytheon.uf.common.colormap;bundle-version="1.12.1174", + com.raytheon.viz.ui;bundle-version="1.12.1174", + javax.vecmath;bundle-version="1.3.1", + com.raytheon.uf.common.util;bundle-version="1.12.1174", + com.raytheon.uf.common.geospatial;bundle-version="1.12.1174" +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Bundle-ActivationPolicy: lazy +Export-Package: com.raytheon.uf.viz.remote.graphics, + com.raytheon.uf.viz.remote.graphics.events, + com.raytheon.uf.viz.remote.graphics.events.clipping, + com.raytheon.uf.viz.remote.graphics.events.colormap, + com.raytheon.uf.viz.remote.graphics.events.drawables, + com.raytheon.uf.viz.remote.graphics.events.fonts, + com.raytheon.uf.viz.remote.graphics.events.imagery, + com.raytheon.uf.viz.remote.graphics.events.mesh, + com.raytheon.uf.viz.remote.graphics.events.mosaic, + com.raytheon.uf.viz.remote.graphics.events.points, + com.raytheon.uf.viz.remote.graphics.events.rendering, + com.raytheon.uf.viz.remote.graphics.events.shapes, + com.raytheon.uf.viz.remote.graphics.events.strings, + com.raytheon.uf.viz.remote.graphics.extensions, + com.raytheon.uf.viz.remote.graphics.objects diff --git a/cave/com.raytheon.uf.viz.remote.graphics/build.properties b/cave/com.raytheon.uf.viz.remote.graphics/build.properties new file mode 100644 index 0000000000..e9863e281e --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/build.properties @@ -0,0 +1,5 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + plugin.xml diff --git a/cave/com.raytheon.uf.viz.remote.graphics/plugin.xml b/cave/com.raytheon.uf.viz.remote.graphics/plugin.xml new file mode 100644 index 0000000000..88ad3a055c --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/plugin.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/Activator.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/Activator.java new file mode 100644 index 0000000000..448ef1b2c4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/Activator.java @@ -0,0 +1,84 @@ +package com.raytheon.uf.viz.remote.graphics; + +import java.awt.image.BufferedImage; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +import com.raytheon.uf.common.serialization.DynamicSerializationManager; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.remote.graphics.adapters.PixelExtentSerializationAdapter; +import com.raytheon.uf.viz.remote.graphics.adapters.RGBSerializationAdapter; +import com.raytheon.uf.viz.remote.graphics.adapters.RectangleAdapter; +import com.raytheon.uf.viz.remote.graphics.adapters.RenderedImageAdapter; + +/** + * The activator class controls the plug-in life cycle + */ +public class Activator extends AbstractUIPlugin { + + public static final IUFStatusHandler statusHandler = UFStatus + .getHandler(Activator.class); + + // The plug-in ID + public static final String PLUGIN_ID = "com.raytheon.uf.viz.remote.graphics"; //$NON-NLS-1$ + + // The shared instance + private static Activator plugin; + + /** + * 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; + DynamicSerializationManager.registerAdapter(PixelExtent.class, + new PixelExtentSerializationAdapter()); + DynamicSerializationManager.registerAdapter(RGB.class, + new RGBSerializationAdapter()); + DynamicSerializationManager.registerAdapter(BufferedImage.class, + new RenderedImageAdapter()); + DynamicSerializationManager.registerAdapter(Rectangle.class, + new RectangleAdapter()); + } + + /* + * (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); + } + + public static IUFStatusHandler getStatusHandler() { + return statusHandler; + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchGraphicsTarget.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchGraphicsTarget.java new file mode 100644 index 0000000000..7769b0a272 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchGraphicsTarget.java @@ -0,0 +1,1379 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics; + +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.colormap.IColorMap; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.DrawableColorMap; +import com.raytheon.uf.viz.core.DrawableImage; +import com.raytheon.uf.viz.core.DrawableLine; +import com.raytheon.uf.viz.core.DrawableString; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IView; +import com.raytheon.uf.viz.core.PixelCoverage; +import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback; +import com.raytheon.uf.viz.core.data.IColormappedDataPreparer; +import com.raytheon.uf.viz.core.data.IDataPreparer; +import com.raytheon.uf.viz.core.data.IImageDataPreparer; +import com.raytheon.uf.viz.core.data.IRenderedImageCallback; +import com.raytheon.uf.viz.core.data.resp.NumericImageData; +import com.raytheon.uf.viz.core.drawables.ColorMapParameters; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IFont; +import com.raytheon.uf.viz.core.drawables.IFont.Style; +import com.raytheon.uf.viz.core.drawables.IImage; +import com.raytheon.uf.viz.core.drawables.IShadedShape; +import com.raytheon.uf.viz.core.drawables.IWireframeShape; +import com.raytheon.uf.viz.core.drawables.ImagingSupport; +import com.raytheon.uf.viz.core.drawables.PaintProperties; +import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension.IGraphicsExtensionInterface; +import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtensionManager; +import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.events.clipping.ClearClippingPane; +import com.raytheon.uf.viz.remote.graphics.events.clipping.SetupClippingPane; +import com.raytheon.uf.viz.remote.graphics.events.colormap.DispatchingColorMapManager; +import com.raytheon.uf.viz.remote.graphics.events.colormap.DrawColorRampEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawCircleEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawCirclesEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawLineEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawLinesEvent; +import com.raytheon.uf.viz.remote.graphics.events.drawables.DrawRectEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.CreateIImageEvent; +import com.raytheon.uf.viz.remote.graphics.events.points.DrawPointsEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.BeginFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.EndFrameEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.CreateShadedShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.CreateWireframeShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.DrawShadedShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.DrawShadedShapesEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.RenderWireframeShapeEvent; +import com.raytheon.uf.viz.remote.graphics.events.strings.DrawStringEvent; +import com.raytheon.uf.viz.remote.graphics.events.strings.DrawStringsEvent; +import com.raytheon.uf.viz.remote.graphics.extensions.DispatchingImagingExtension; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingFont; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingImage; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingImage.DispatchingRenderedImageCallback; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingShadedShape; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingWireframeShape; + +/** + * Graphics target that uses a dispatcher for dispatching graphics events. These + * events involve rendering and creating render objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 28, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DispatchGraphicsTarget extends DispatchingObject + implements IGraphicsTarget { + + private static final transient IUFStatusHandler statusHandler = UFStatus + .getHandler(DispatchGraphicsTarget.class); + + private IFont defaultFont; + + private RGB backgroundColor = new RGB(0, 0, 0); + + private GraphicsExtensionManager extensionManager; + + private Rectangle bounds; + + public DispatchGraphicsTarget(IGraphicsTarget target, Canvas canvas, + Dispatcher dispatcher) { + super(target, dispatcher); + extensionManager = new GraphicsExtensionManager(this); + bounds = canvas.getBounds(); + canvas.addListener(SWT.Resize, new Listener() { + @Override + public void handleEvent(Event event) { + bounds = ((Canvas) event.widget).getBounds(); + } + }); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IGraphicsTarget#initializeRaster(com.raytheon + * .uf.viz.core.data.IDataPreparer, + * com.raytheon.uf.viz.core.drawables.ColorMapParameters) + */ + @Override + public IImage initializeRaster(IDataPreparer preparer, + ColorMapParameters optionalParams) { + IImage rval = null; + if (optionalParams == null) { + // Assume IImageDataPreparer + final IImageDataPreparer imagePreparer = (IImageDataPreparer) preparer; + rval = initializeRaster(new IRenderedImageCallback() { + @Override + public RenderedImage getImage() throws VizException { + return imagePreparer.prepareData().getImage(); + } + }); + } else if (preparer instanceof IColormappedDataPreparer) { + try { + IColormappedImageExtension cmapExt = getExtension(IColormappedImageExtension.class); + final IColormappedDataPreparer cmapPreparer = (IColormappedDataPreparer) preparer; + rval = cmapExt.initializeRaster( + new IColorMapDataRetrievalCallback() { + @Override + public ColorMapData getColorMapData() + throws VizException { + NumericImageData oldData = cmapPreparer + .prepareData(); + return new ColorMapData( + oldData.getData(), + new int[] { + oldData.getDatasetBounds().width, + oldData.getDatasetBounds().height }); + } + + }, optionalParams); + } catch (VizException e) { + statusHandler.handle(Priority.PROBLEM, + "Error constructing creating image", e); + } + } + return rval; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IGraphicsTarget#initializeRaster(com.raytheon + * .uf.viz.core.data.IRenderedImageCallback) + */ + @Override + public IImage initializeRaster(IRenderedImageCallback imageCallback) { + // Create callback wrapper + DispatchingRenderedImageCallback wrappedCallback = new DispatchingRenderedImageCallback( + imageCallback); + // Create image from wrapped target and return DispatchingImage + DispatchingImage image = new DispatchingImage( + wrappedObject.initializeRaster(wrappedCallback), + DispatchingImagingExtension.class, wrappedCallback, + getDispatcher()); + // Send creation event + dispatch(RemoteGraphicsEventFactory.createEvent( + CreateIImageEvent.class, image)); + return image; + } + + /** + * @param font + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#initializeFont(java.lang.String) + */ + public IFont initializeFont(String font) { + return new DispatchingFont(wrappedObject.initializeFont(font), + getDispatcher()); + } + + /** + * @param fontName + * @param size + * @param styles + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#initializeFont(java.lang.String, + * float, com.raytheon.uf.viz.core.drawables.IFont.Style[]) + */ + public IFont initializeFont(String fontName, float size, Style[] styles) { + return new DispatchingFont(wrappedObject.initializeFont(fontName, size, + styles), getDispatcher()); + } + + /** + * @param fontFile + * @param size + * @param styles + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#initializeFont(java.io.File, + * float, com.raytheon.uf.viz.core.drawables.IFont.Style[]) + */ + public IFont initializeFont(File fontFile, float size, Style[] styles) { + return new DispatchingFont(wrappedObject.initializeFont(fontFile, size, + styles), getDispatcher(), fontFile); + } + + /** + * @param image + * @param extent + * @param paintProps + * @return + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawRaster(com.raytheon.uf.viz.core.drawables.IImage, + * com.raytheon.uf.viz.core.PixelCoverage, + * com.raytheon.uf.viz.core.drawables.PaintProperties) + */ + public boolean drawRaster(IImage image, PixelCoverage extent, + PaintProperties paintProps) throws VizException { + DrawableImage di = new DrawableImage(image, extent); + return drawRasters(paintProps, di); + } + + /** + * @param paintProps + * @param images + * @return + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawRasters(com.raytheon.uf.viz.core.drawables.PaintProperties, + * com.raytheon.uf.viz.core.DrawableImage[]) + */ + public boolean drawRasters(PaintProperties paintProps, + DrawableImage... images) throws VizException { + return ImagingSupport.drawRasters(this, paintProps, images); + } + + /** + * @param image + * @param extent + * @param paintProps + * @param mode + * @return + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawRaster(com.raytheon.uf.viz.core.drawables.IImage, + * com.raytheon.uf.viz.core.PixelCoverage, + * com.raytheon.uf.viz.core.drawables.PaintProperties, + * com.raytheon.uf.viz.core.IGraphicsTarget.RasterMode) + */ + public boolean drawRaster(IImage image, PixelCoverage extent, + PaintProperties paintProps, RasterMode mode) throws VizException { + DrawableImage di = new DrawableImage(image, extent); + di.setMode(mode); + return drawRasters(paintProps, di); + } + + /** + * @param parameters + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawStrings(com.raytheon.uf.viz.core.DrawableString[]) + */ + public void drawStrings(DrawableString... parameters) throws VizException { + drawStrings(Arrays.asList(parameters)); + } + + /** + * @param parameters + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawStrings(java.util.Collection) + */ + public void drawStrings(Collection parameters) + throws VizException { + List originalFonts = new ArrayList(parameters.size()); + for (DrawableString string : parameters) { + originalFonts.add(string.font); + if (string.font instanceof DispatchingFont) { + DispatchingFont font = (DispatchingFont) string.font; + font.flushState(); + string.font = font.getWrappedObject(); + } + } + wrappedObject.drawStrings(parameters); + + Iterator stringIter = parameters.iterator(); + Iterator fontIter = originalFonts.iterator(); + while (stringIter.hasNext() && fontIter.hasNext()) { + stringIter.next().font = fontIter.next(); + } + + DrawStringsEvent event = RemoteGraphicsEventFactory.createEvent( + DrawStringsEvent.class, this); + DrawStringEvent[] strings = new DrawStringEvent[parameters.size()]; + int i = 0; + for (DrawableString param : parameters) { + strings[i] = RemoteGraphicsEventFactory.createEvent( + DrawStringEvent.class, this); + strings[i].setDrawableString(param); + ++i; + } + event.setObjects(strings); + dispatch(event); + } + + /** + * @param parameters + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getStringsBounds(com.raytheon.uf.viz.core.DrawableString) + */ + public Rectangle2D getStringsBounds(DrawableString parameters) { + IFont font = parameters.font; + if (font instanceof DispatchingFont) { + parameters.font = ((DispatchingFont) font).getWrappedObject(); + } + Rectangle2D rval = wrappedObject.getStringsBounds(parameters); + parameters.font = font; + return rval; + } + + /** + * @param parameters + * @param string + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getStringsBounds(com.raytheon.uf.viz.core.DrawableString, + * java.lang.String) + */ + public Rectangle2D getStringsBounds(DrawableString parameters, String string) { + IFont font = parameters.font; + if (font instanceof DispatchingFont) { + parameters.font = ((DispatchingFont) font).getWrappedObject(); + } + Rectangle2D rval = wrappedObject.getStringsBounds(parameters, string); + parameters.font = font; + return rval; + } + + /** + * @param shape + * @param alpha + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawShadedShape(com.raytheon.uf.viz.core.drawables.IShadedShape, + * float) + */ + public void drawShadedShape(IShadedShape shape, float alpha) + throws VizException { + drawShadedShape(shape, alpha, 1.0f); + } + + /** + * @param shape + * @param alpha + * @param brightness + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawShadedShape(com.raytheon.uf.viz.core.drawables.IShadedShape, + * float, float) + */ + public void drawShadedShape(IShadedShape shape, float alpha, + float brightness) throws VizException { + drawShadedShapes(alpha, brightness, shape); + } + + /** + * @param alpha + * @param brightness + * @param shapes + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawShadedShapes(float, + * float, com.raytheon.uf.viz.core.drawables.IShadedShape[]) + */ + public void drawShadedShapes(float alpha, float brightness, + IShadedShape... shapes) throws VizException { + IShadedShape[] actualShapes = new IShadedShape[shapes.length]; + DrawShadedShapeEvent[] shapeEvents = new DrawShadedShapeEvent[shapes.length]; + DrawShadedShapesEvent event = RemoteGraphicsEventFactory.createEvent( + DrawShadedShapesEvent.class, this); + event.setAlpha(alpha); + event.setBrightness(brightness); + for (int i = 0; i < shapes.length; ++i) { + DispatchingShadedShape shape = (DispatchingShadedShape) shapes[i]; + shape.flushState(); + shapeEvents[i] = RemoteGraphicsEventFactory.createEvent( + DrawShadedShapeEvent.class, (DispatchingShadedShape) shape); + actualShapes[i] = shape.getWrappedObject(); + } + event.setObjects(shapeEvents); + dispatch(event); + + // Actual draw + wrappedObject.drawShadedShapes(alpha, brightness, actualShapes); + } + + /** + * @param shape + * @param color + * @param lineWidth + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawWireframeShape(com.raytheon.uf.viz.core.drawables.IWireframeShape, + * org.eclipse.swt.graphics.RGB, float) + */ + public void drawWireframeShape(IWireframeShape shape, RGB color, + float lineWidth) throws VizException { + DispatchingWireframeShape wrapper = (DispatchingWireframeShape) shape; + shape = wrapper.getWrappedObject(); + wrappedObject.drawWireframeShape(shape, color, lineWidth); + sendDrawWireframeShapeEvent(wrapper, color, lineWidth, null, null, null); + } + + /** + * @param shape + * @param color + * @param lineWidth + * @param lineStyle + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawWireframeShape(com.raytheon.uf.viz.core.drawables.IWireframeShape, + * org.eclipse.swt.graphics.RGB, float, + * com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle) + */ + public void drawWireframeShape(IWireframeShape shape, RGB color, + float lineWidth, LineStyle lineStyle) throws VizException { + DispatchingWireframeShape wrapper = (DispatchingWireframeShape) shape; + shape = wrapper.getWrappedObject(); + wrappedObject.drawWireframeShape(shape, color, lineWidth, lineStyle); + sendDrawWireframeShapeEvent(wrapper, color, lineWidth, lineStyle, null, + null); + } + + /** + * @param shape + * @param color + * @param lineWidth + * @param lineStyle + * @param alpha + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawWireframeShape(com.raytheon.uf.viz.core.drawables.IWireframeShape, + * org.eclipse.swt.graphics.RGB, float, + * com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle, float) + */ + public void drawWireframeShape(IWireframeShape shape, RGB color, + float lineWidth, LineStyle lineStyle, float alpha) + throws VizException { + DispatchingWireframeShape wrapper = (DispatchingWireframeShape) shape; + shape = wrapper.getWrappedObject(); + wrappedObject.drawWireframeShape(shape, color, lineWidth, lineStyle, + alpha); + sendDrawWireframeShapeEvent(wrapper, color, lineWidth, lineStyle, null, + alpha); + } + + /** + * @param shape + * @param color + * @param lineWidth + * @param lineStyle + * @param font + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawWireframeShape(com.raytheon.uf.viz.core.drawables.IWireframeShape, + * org.eclipse.swt.graphics.RGB, float, + * com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle, + * com.raytheon.uf.viz.core.drawables.IFont) + */ + public void drawWireframeShape(IWireframeShape shape, RGB color, + float lineWidth, LineStyle lineStyle, IFont font) + throws VizException { + DispatchingWireframeShape wrapper = (DispatchingWireframeShape) shape; + shape = wrapper.getWrappedObject(); + wrappedObject.drawWireframeShape(shape, color, lineWidth, lineStyle, + ((DispatchingFont) font).getWrappedObject()); + sendDrawWireframeShapeEvent(wrapper, color, lineWidth, lineStyle, font, + null); + } + + /** + * @param shape + * @param color + * @param lineWidth + * @param lineStyle + * @param font + * @param alpha + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawWireframeShape(com.raytheon.uf.viz.core.drawables.IWireframeShape, + * org.eclipse.swt.graphics.RGB, float, + * com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle, + * com.raytheon.uf.viz.core.drawables.IFont, float) + */ + public void drawWireframeShape(IWireframeShape shape, RGB color, + float lineWidth, LineStyle lineStyle, IFont font, float alpha) + throws VizException { + DispatchingWireframeShape wrapper = (DispatchingWireframeShape) shape; + shape = wrapper.getWrappedObject(); + if (font instanceof DispatchingFont) { + font = ((DispatchingFont) font).getWrappedObject(); + } + wrappedObject.drawWireframeShape(shape, color, lineWidth, lineStyle, + font, alpha); + sendDrawWireframeShapeEvent(wrapper, color, lineWidth, lineStyle, font, + alpha); + } + + private void sendDrawWireframeShapeEvent(DispatchingWireframeShape shape, + RGB color, float lineWidth, LineStyle lineStyle, IFont font, + Float alpha) { + shape.flushState(); + RenderWireframeShapeEvent event = RemoteGraphicsEventFactory + .createEvent(RenderWireframeShapeEvent.class, shape); + event.setColor(color); + event.setLineWidth(lineWidth); + event.setLineStyle(lineStyle); + event.setAlpha(alpha); + if (font instanceof DispatchingFont) { + DispatchingFont df = (DispatchingFont) font; + df.flushState(); + event.setFontId(df.getObjectId()); + } + dispatch(event); + } + + /** + * @param pe + * @param color + * @param lineWidth + * @param alpha + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawRect(com.raytheon.uf.viz.core.IExtent, + * org.eclipse.swt.graphics.RGB, float, double) + */ + public void drawRect(IExtent pe, RGB color, float lineWidth, double alpha) + throws VizException { + wrappedObject.drawRect(pe, color, lineWidth, alpha); + drawRect(pe, color, (float) alpha, 1.0f, false, null); + } + + /** + * @param pe + * @param color + * @param alpha + * @param pattern + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawShadedRect(com.raytheon.uf.viz.core.IExtent, + * org.eclipse.swt.graphics.RGB, double, byte[]) + */ + public void drawShadedRect(IExtent pe, RGB color, double alpha, + byte[] pattern) throws VizException { + wrappedObject.drawShadedRect(pe, color, alpha, pattern); + drawRect(pe, color, (float) alpha, 1.0f, true, pattern); + } + + private void drawRect(IExtent pe, RGB color, float alpha, float lineWidth, + boolean filled, byte[] pattern) { + DrawRectEvent event = RemoteGraphicsEventFactory.createEvent( + DrawRectEvent.class, this); + event.setExtent(pe); + event.setColor(color); + event.setAlpha(alpha); + event.setLineWidth(lineWidth); + event.setFilled(filled); + event.setFillPattern(pattern); + dispatch(event); + } + + /** + * @param circles + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawCircle(com.raytheon.uf.viz.core.DrawableCircle[]) + */ + public void drawCircle(DrawableCircle... circles) throws VizException { + wrappedObject.drawCircle(circles); + DrawCirclesEvent event = RemoteGraphicsEventFactory.createEvent( + DrawCirclesEvent.class, this); + DrawCircleEvent[] events = new DrawCircleEvent[circles.length]; + for (int i = 0; i < circles.length; ++i) { + events[i] = RemoteGraphicsEventFactory.createEvent( + DrawCircleEvent.class, this); + events[i].setDrawableCircle(circles[i]); + } + event.setObjects(events); + dispatch(event); + } + + /** + * @param lines + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawLine(com.raytheon.uf.viz.core.DrawableLine[]) + */ + public void drawLine(DrawableLine... lines) throws VizException { + wrappedObject.drawLine(lines); + DrawLinesEvent event = RemoteGraphicsEventFactory.createEvent( + DrawLinesEvent.class, this); + DrawLineEvent[] events = new DrawLineEvent[lines.length]; + for (int i = 0; i < lines.length; ++i) { + events[i] = RemoteGraphicsEventFactory.createEvent( + DrawLineEvent.class, this); + events[i].setDrawableLine(lines[i]); + } + event.setObjects(events); + dispatch(event); + } + + /** + * @param x1 + * @param y1 + * @param z1 + * @param radius + * @param color + * @param width + * @param startAzimuth + * @param endAzimuth + * @param lineStyle + * @param includeSides + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawArc(double, double, + * double, double, org.eclipse.swt.graphics.RGB, float, int, int, + * com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle, boolean) + */ + @Deprecated + public void drawArc(double x1, double y1, double z1, double radius, + RGB color, float width, int startAzimuth, int endAzimuth, + LineStyle lineStyle, boolean includeSides) throws VizException { + DrawableCircle dc = new DrawableCircle(); + dc.setCoordinates(x1, y1, z1); + dc.basics.color = color; + dc.lineStyle = lineStyle; + dc.startAzimuth = startAzimuth; + dc.endAzimuth = endAzimuth; + if (startAzimuth > endAzimuth) { + endAzimuth += 360; + } + dc.numberOfPoints = endAzimuth - startAzimuth; + dc.includeSides = includeSides; + dc.lineWidth = width; + dc.radius = radius; + drawCircle(dc); + } + + /** + * @param x1 + * @param y1 + * @param z1 + * @param radius + * @param angle + * @return + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getPointOnCircle(double, + * double, double, double, double) + */ + public double[] getPointOnCircle(double x1, double y1, double z1, + double radius, double angle) throws VizException { + return wrappedObject.getPointOnCircle(x1, y1, z1, radius, angle); + } + + /** + * @param mutable + * @param descriptor + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createWireframeShape(boolean, + * com.raytheon.uf.viz.core.drawables.IDescriptor) + */ + public IWireframeShape createWireframeShape(boolean mutable, + IDescriptor descriptor) { + // Create original + IWireframeShape targetShape = wrappedObject.createWireframeShape( + mutable, descriptor); + // Create wrapped + DispatchingWireframeShape dispatching = new DispatchingWireframeShape( + targetShape, getDispatcher(), descriptor.getGridGeometry()); + // Dispatch creation event + sendCreateWireframeShapeEvent(dispatching, mutable, + descriptor.getGridGeometry(), null, null, null); + return dispatching; + } + + /** + * @param mutable + * @param descriptor + * @param simplificationLevel + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createWireframeShape(boolean, + * com.raytheon.uf.viz.core.drawables.IDescriptor, float) + */ + public IWireframeShape createWireframeShape(boolean mutable, + IDescriptor descriptor, float simplificationLevel) { + // Create original + IWireframeShape targetShape = wrappedObject.createWireframeShape( + mutable, descriptor, simplificationLevel); + // Create wrapped + DispatchingWireframeShape dispatching = new DispatchingWireframeShape( + targetShape, getDispatcher(), descriptor.getGridGeometry()); + // Dispatch creation event + sendCreateWireframeShapeEvent(dispatching, mutable, + descriptor.getGridGeometry(), simplificationLevel, null, null); + return dispatching; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IGraphicsTarget#createWireframeShape(boolean, + * org.geotools.coverage.grid.GeneralGridGeometry, float) + */ + @Override + public IWireframeShape createWireframeShape(boolean mutable, + GeneralGridGeometry geom, float simplificationLevel) { + // Create original + IWireframeShape targetShape = wrappedObject.createWireframeShape( + mutable, geom, simplificationLevel); + // Create wrapped + DispatchingWireframeShape dispatching = new DispatchingWireframeShape( + targetShape, getDispatcher(), geom); + // Dispatch creation event + sendCreateWireframeShapeEvent(dispatching, mutable, geom, + simplificationLevel, null, null); + return dispatching; + } + + /** + * @param mutable + * @param descriptor + * @param simplificationLevel + * @param spatialChopFlag + * @param extent + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createWireframeShape(boolean, + * com.raytheon.uf.viz.core.drawables.IDescriptor, float, boolean, + * com.raytheon.uf.viz.core.IExtent) + */ + public IWireframeShape createWireframeShape(boolean mutable, + IDescriptor descriptor, float simplificationLevel, + boolean spatialChopFlag, IExtent extent) { + // Create original + IWireframeShape targetShape = wrappedObject.createWireframeShape( + mutable, descriptor, simplificationLevel, spatialChopFlag, + extent); + // Create wrapped + DispatchingWireframeShape dispatching = new DispatchingWireframeShape( + targetShape, getDispatcher(), descriptor.getGridGeometry()); + // Dispatch creation event + sendCreateWireframeShapeEvent(dispatching, mutable, + descriptor.getGridGeometry(), simplificationLevel, + spatialChopFlag, extent); + return dispatching; + } + + /** + * @param mutableFlag + * @param geom + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createWireframeShape(boolean, + * org.geotools.coverage.grid.GeneralGridGeometry) + */ + public IWireframeShape createWireframeShape(boolean mutableFlag, + GeneralGridGeometry geom) { + // Create original + IWireframeShape targetShape = wrappedObject.createWireframeShape( + mutableFlag, geom); + // Create wrapped + DispatchingWireframeShape dispatching = new DispatchingWireframeShape( + targetShape, getDispatcher(), geom); + // Dispatch creation event + sendCreateWireframeShapeEvent(dispatching, mutableFlag, geom, null, + null, null); + return dispatching; + } + + /** + * @param mutable + * @param geom + * @param simplificationLevel + * @param spatialChopFlag + * @param extent + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createWireframeShape(boolean, + * org.geotools.coverage.grid.GeneralGridGeometry, float, boolean, + * com.raytheon.uf.viz.core.IExtent) + */ + public IWireframeShape createWireframeShape(boolean mutable, + GeneralGridGeometry geom, float simplificationLevel, + boolean spatialChopFlag, IExtent extent) { + // Create original + IWireframeShape targetShape = wrappedObject.createWireframeShape( + mutable, geom, simplificationLevel, spatialChopFlag, extent); + // Create wrapped + DispatchingWireframeShape dispatching = new DispatchingWireframeShape( + targetShape, getDispatcher(), geom); + // Dispatch creation event + sendCreateWireframeShapeEvent(dispatching, mutable, geom, + simplificationLevel, spatialChopFlag, extent); + return dispatching; + + } + + private void sendCreateWireframeShapeEvent(DispatchingWireframeShape shape, + boolean mutable, GeneralGridGeometry geom, + Float simplificationLevel, Boolean spatialChopFlag, IExtent extent) { + CreateWireframeShapeEvent event = RemoteGraphicsEventFactory + .createEvent(CreateWireframeShapeEvent.class, shape); + event.setGridGeometry(geom); + event.setMutable(mutable); + event.setIExtent(extent); + event.setSimplificationLevel(simplificationLevel); + event.setSpatialChopFlag(spatialChopFlag); + dispatch(event); + } + + /** + * @param mutable + * @param descriptor + * @param tesselate + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createShadedShape(boolean, + * com.raytheon.uf.viz.core.drawables.IDescriptor, boolean) + */ + @Deprecated + public IShadedShape createShadedShape(boolean mutable, + IDescriptor descriptor, boolean tesselate) { + return createShadedShape(mutable, descriptor.getGridGeometry(), + tesselate); + } + + /** + * @param mutable + * @param descriptor + * @param tesselate + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#createShadedShape(boolean, + * com.raytheon.uf.viz.core.drawables.IDescriptor, boolean) + */ + public IShadedShape createShadedShape(boolean mutable, + GeneralGridGeometry targetGeometry, boolean tesselate) { + DispatchingShadedShape shape = new DispatchingShadedShape( + wrappedObject.createShadedShape(mutable, targetGeometry, + tesselate), getDispatcher()); + // Send creation event + CreateShadedShapeEvent event = RemoteGraphicsEventFactory.createEvent( + CreateShadedShapeEvent.class, shape); + event.setTargetGeometry(targetGeometry); + event.setMutable(mutable); + event.setTesselate(tesselate); + dispatch(event); + return shape; + } + + /** + * + * @see com.raytheon.uf.viz.core.IGraphicsTarget#init() + */ + public void init() { + wrappedObject.init(); + defaultFont = new DispatchingFont(wrappedObject.getDefaultFont(), + getDispatcher()); + } + + /** + * @param display + * @param isClearBackground + * @see com.raytheon.uf.viz.core.IGraphicsTarget#beginFrame(com.raytheon.uf.viz.core.IView, + * boolean) + */ + public void beginFrame(IView view, boolean isClearBackground) { + wrappedObject.beginFrame(view, isClearBackground); + BeginFrameEvent beginFrame = RemoteGraphicsEventFactory.createEvent( + BeginFrameEvent.class, this); + beginFrame.setExtent(view.getExtent().clone()); + beginFrame.setColor(backgroundColor); + beginFrame.setBounds(bounds); + dispatch(beginFrame); + } + + /** + * + * @see com.raytheon.uf.viz.core.IGraphicsTarget#endFrame() + */ + public void endFrame() { + wrappedObject.endFrame(); + dispatch(RemoteGraphicsEventFactory.createEvent(EndFrameEvent.class, + this)); + } + + /** + * + * @see com.raytheon.uf.viz.core.IGraphicsTarget#resize() + */ + public void resize() { + wrappedObject.resize(); + } + + /** + * + * @see com.raytheon.uf.viz.core.IGraphicsTarget#dispose() + */ + public void dispose() { + wrappedObject.dispose(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#screenshot() + */ + public BufferedImage screenshot() { + return wrappedObject.screenshot(); + } + + /** + * @param extent + * @see com.raytheon.uf.viz.core.IGraphicsTarget#setupClippingPlane(com.raytheon.uf.viz.core.IExtent) + */ + public void setupClippingPlane(IExtent extent) { + wrappedObject.setupClippingPlane(extent); + SetupClippingPane event = RemoteGraphicsEventFactory.createEvent( + SetupClippingPane.class, this); + event.setExtent(extent); + dispatch(event); + } + + /** + * + * @see com.raytheon.uf.viz.core.IGraphicsTarget#clearClippingPlane() + */ + public void clearClippingPlane() { + wrappedObject.clearClippingPlane(); + dispatch(RemoteGraphicsEventFactory.createEvent( + ClearClippingPane.class, this)); + } + + /** + * @param needsRefresh + * @see com.raytheon.uf.viz.core.IGraphicsTarget#setNeedsRefresh(boolean) + */ + public void setNeedsRefresh(boolean needsRefresh) { + wrappedObject.setNeedsRefresh(needsRefresh); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#isNeedsRefresh() + */ + public boolean isNeedsRefresh() { + return wrappedObject.isNeedsRefresh(); + } + + /** + * @param backgroundColor + * @see com.raytheon.uf.viz.core.IGraphicsTarget#setBackgroundColor(org.eclipse.swt.graphics.RGB) + */ + public void setBackgroundColor(RGB backgroundColor) { + this.backgroundColor = backgroundColor; + wrappedObject.setBackgroundColor(backgroundColor); + } + + /** + * @param isColorbarDisplayed + * @see com.raytheon.uf.viz.core.IGraphicsTarget#setUseBuiltinColorbar(boolean) + */ + public void setUseBuiltinColorbar(boolean isColorbarDisplayed) { + wrappedObject.setUseBuiltinColorbar(isColorbarDisplayed); + } + + /** + * @param colorMap + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawColorRamp(com.raytheon.uf.viz.core.DrawableColorMap) + */ + public void drawColorRamp(DrawableColorMap colorMap) throws VizException { + wrappedObject.drawColorRamp(colorMap); + DrawColorRampEvent event = RemoteGraphicsEventFactory.createEvent( + DrawColorRampEvent.class, this); + event.setDrawableColorMap(colorMap, + DispatchingColorMapManager.getInstance(getDispatcher()) + .getColorMapId(colorMap.getColorMapParams())); + dispatch(event); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getDefaultFont() + */ + public IFont getDefaultFont() { + return defaultFont; + } + + /** + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getView() + */ + @Override + public IView getView() { + return wrappedObject.getView(); + } + + /** + * @return + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getViewType() + */ + public String getViewType() { + return wrappedObject.getViewType(); + } + + /** + * @param x + * @param y + * @param z + * @param color + * @param pointStyle + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawPoint(double, double, + * double, org.eclipse.swt.graphics.RGB, + * com.raytheon.uf.viz.core.IGraphicsTarget.PointStyle) + */ + public void drawPoint(double x, double y, double z, RGB color, + PointStyle pointStyle) throws VizException { + wrappedObject.drawPoint(x, y, z, color, pointStyle); + sendDrawPointsEvent(Arrays.asList(new double[] { x, y, z }), color, + pointStyle, 1.0f); + } + + /** + * @param locations + * @param color + * @param pointStyle + * @param magnification + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawPoints(java.util.Collection, + * org.eclipse.swt.graphics.RGB, + * com.raytheon.uf.viz.core.IGraphicsTarget.PointStyle, float) + */ + public void drawPoints(Collection locations, RGB color, + PointStyle pointStyle, float magnification) throws VizException { + wrappedObject.drawPoints(locations, color, pointStyle, magnification); + sendDrawPointsEvent(locations, color, pointStyle, magnification); + } + + /** + * @param x + * @param y + * @param z + * @param color + * @param pointStyle + * @param magnification + * @throws VizException + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawPoint(double, double, + * double, org.eclipse.swt.graphics.RGB, + * com.raytheon.uf.viz.core.IGraphicsTarget.PointStyle, float) + */ + public void drawPoint(double x, double y, double z, RGB color, + PointStyle pointStyle, float magnification) throws VizException { + wrappedObject.drawPoint(x, y, z, color, pointStyle, magnification); + sendDrawPointsEvent(Arrays.asList(new double[] { x, y, z }), color, + pointStyle, magnification); + } + + private void sendDrawPointsEvent(Collection points, RGB color, + PointStyle pointStyle, float magnification) { + DrawPointsEvent event = RemoteGraphicsEventFactory.createEvent( + DrawPointsEvent.class, this); + event.addPoints(points); + event.setColor(color); + event.setStyle(pointStyle); + event.setMagnification(magnification); + dispatch(event); + } + + /** + * @param font + * @param text + * @param x + * @param y + * @param z + * @param textStyle + * @param color + * @param horizontalAlignment + * @param verticalAlignment + * @param rotation + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawString(com.raytheon.uf.viz.core.drawables.IFont, + * java.lang.String, double, double, double, + * com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle, + * org.eclipse.swt.graphics.RGB, + * com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment, + * com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment, + * java.lang.Double) + */ + public void drawString(IFont font, String text, double x, double y, + double z, TextStyle textStyle, RGB color, + HorizontalAlignment horizontalAlignment, + VerticalAlignment verticalAlignment, Double rotation) + throws VizException { + DrawableString string = new DrawableString(text, color); + string.setCoordinates(x, y, z); + string.font = font; + string.textStyle = textStyle; + string.horizontalAlignment = horizontalAlignment; + string.verticallAlignment = verticalAlignment; + string.rotation = rotation; + drawStrings(string); + } + + /** + * @param font + * @param text + * @param x + * @param y + * @param z + * @param textStyle + * @param color + * @param horizontalAlignment + * @param rotation + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawString(com.raytheon.uf.viz.core.drawables.IFont, + * java.lang.String, double, double, double, + * com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle, + * org.eclipse.swt.graphics.RGB, + * com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment, + * java.lang.Double) + */ + public void drawString(IFont font, String text, double x, double y, + double z, TextStyle textStyle, RGB color, + HorizontalAlignment horizontalAlignment, Double rotation) + throws VizException { + DrawableString string = new DrawableString(text, color); + string.setCoordinates(x, y, z); + string.font = font; + string.textStyle = textStyle; + string.horizontalAlignment = horizontalAlignment; + string.rotation = rotation; + drawStrings(string); + } + + /** + * @param font + * @param text + * @param x + * @param y + * @param z + * @param textStyle + * @param colors + * @param horizontalAlignment + * @param verticalAlignment + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawStrings(com.raytheon.uf.viz.core.drawables.IFont, + * java.lang.String[], double, double, double, + * com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle, + * org.eclipse.swt.graphics.RGB[], + * com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment, + * com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment) + */ + public void drawStrings(IFont font, String[] text, double x, double y, + double z, TextStyle textStyle, RGB[] colors, + HorizontalAlignment horizontalAlignment, + VerticalAlignment verticalAlignment) throws VizException { + DrawableString string = new DrawableString(text, colors); + string.setCoordinates(x, y, z); + string.font = font; + string.textStyle = textStyle; + string.horizontalAlignment = horizontalAlignment; + string.verticallAlignment = verticalAlignment; + drawStrings(string); + } + + /** + * @param font + * @param string + * @param xPos + * @param yPos + * @param zPos + * @param textStyle + * @param color + * @param horizontalAlignment + * @param verticalAlignment + * @param rotation + * @param alpha + * @param magnification + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawString(com.raytheon.uf.viz.core.drawables.IFont, + * java.lang.String, double, double, double, + * com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle, + * org.eclipse.swt.graphics.RGB, + * com.raytheon.uf.viz.core.IGraphicsTarget.HorizontalAlignment, + * com.raytheon.uf.viz.core.IGraphicsTarget.VerticalAlignment, + * java.lang.Double, float, double) + */ + public void drawString(IFont font, String text, double x, double y, + double z, TextStyle textStyle, RGB color, + HorizontalAlignment horizontalAlignment, + VerticalAlignment verticalAlignment, Double rotation, float alpha, + double magnification) throws VizException { + DrawableString string = new DrawableString(text, color); + string.setCoordinates(x, y, z); + string.font = font; + string.textStyle = textStyle; + string.horizontalAlignment = horizontalAlignment; + string.verticallAlignment = verticalAlignment; + string.rotation = rotation; + string.basics.alpha = alpha; + string.magnification = magnification; + drawStrings(string); + } + + /** + * @param font + * @param text + * @return + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getStringBounds(com.raytheon.uf.viz.core.drawables.IFont, + * java.lang.String) + */ + public Rectangle2D getStringBounds(IFont font, String text) { + if (font instanceof DispatchingFont) { + font = ((DispatchingFont) font).getWrappedObject(); + } + return wrappedObject.getStringBounds(font, text); + } + + /** + * @param font + * @param text + * @param style + * @return + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#getStringBounds(com.raytheon.uf.viz.core.drawables.IFont, + * java.lang.String[], + * com.raytheon.uf.viz.core.IGraphicsTarget.TextStyle) + */ + public Rectangle2D getStringBounds(IFont font, String[] text, + TextStyle style) { + if (font instanceof DispatchingFont) { + font = ((DispatchingFont) font).getWrappedObject(); + } + return wrappedObject.getStringBounds(font, text, style); + } + + /** + * @param x1 + * @param y1 + * @param z1 + * @param radius + * @param color + * @param width + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawCircle(double, double, + * double, double, org.eclipse.swt.graphics.RGB, float) + */ + public void drawCircle(double x1, double y1, double z1, double radius, + RGB color, float width) throws VizException { + wrappedObject.drawCircle(x1, y1, z1, radius, color, width); + } + + /** + * @param x + * @param y + * @param z + * @param radius + * @param color + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawFilledCircle(double, + * double, double, double, org.eclipse.swt.graphics.RGB) + */ + public void drawFilledCircle(double x, double y, double z, double radius, + RGB color) throws VizException { + wrappedObject.drawFilledCircle(x, y, z, radius, color); + } + + /** + * @param name + * @return + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#buildColorMap(java.lang.String) + */ + public IColorMap buildColorMap(String name) throws VizException { + return wrappedObject.buildColorMap(name); + } + + /** + * @param x1 + * @param y1 + * @param z1 + * @param x2 + * @param y2 + * @param z2 + * @param color + * @param width + * @param lineStyle + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawLine(double, double, + * double, double, double, double, org.eclipse.swt.graphics.RGB, float, + * com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle) + */ + public void drawLine(double x1, double y1, double z1, double x2, double y2, + double z2, RGB color, float width, LineStyle lineStyle) + throws VizException { + DrawableLine dl = new DrawableLine(); + dl.addPoint(x1, y1, z1); + dl.addPoint(x2, y2, z2); + dl.basics.color = color; + dl.width = width; + dl.lineStyle = lineStyle; + drawLine(dl); + } + + /** + * @param x1 + * @param y1 + * @param z1 + * @param x2 + * @param y2 + * @param z2 + * @param color + * @param width + * @throws VizException + * @deprecated + * @see com.raytheon.uf.viz.core.IGraphicsTarget#drawLine(double, double, + * double, double, double, double, org.eclipse.swt.graphics.RGB, float) + */ + public void drawLine(double x1, double y1, double z1, double x2, double y2, + double z2, RGB color, float width) throws VizException { + drawLine(x1, y1, z1, x2, y2, z2, color, width, LineStyle.DEFAULT); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.IGraphicsTarget#getExtension(java.lang.Class) + */ + @Override + public T getExtension( + Class extensionClass) throws VizException { + return extensionManager.getExtension(extensionClass); + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/Dispatcher.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/Dispatcher.java new file mode 100644 index 0000000000..b33ec702d2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/Dispatcher.java @@ -0,0 +1,70 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics; + +import com.raytheon.uf.viz.remote.graphics.events.AbstractRemoteGraphicsEvent; + +/** + * Abstract class that is responsible for dispatching remote graphics events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 28, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public abstract class Dispatcher { + + private static int dispatcherIdCounter = 0; + + private int objectCounter = 0; + + private int dispatcherId; + + protected Dispatcher() { + dispatcherId = newDispatcherId(); + } + + public static synchronized int newDispatcherId() { + return ++dispatcherIdCounter; + } + + public synchronized int newObjectId() { + return ++objectCounter; + } + + /** + * @return the displayId + */ + public int getDispatcherId() { + return dispatcherId; + } + + public abstract void dispatch(AbstractRemoteGraphicsEvent eventObject); + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatcherFactory.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatcherFactory.java new file mode 100644 index 0000000000..795f8d63d1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatcherFactory.java @@ -0,0 +1,52 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics; + +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; + +/** + * Factory for creating Dispatcher objects for dispatching remote graphics + * events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface DispatcherFactory { + + /** + * Creates a new Dispatcher object for dispatching events + * + * @return + */ + public Dispatcher createNewDispatcher(IRenderableDisplay display) + throws InstantiationException; + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java new file mode 100644 index 0000000000..a53abadedc --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingGraphicsFactory.java @@ -0,0 +1,229 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics; + +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Canvas; +import org.eclipse.swt.widgets.Composite; +import org.opengis.coverage.grid.GridEnvelope; + +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter; +import com.raytheon.uf.viz.core.IDisplayPane; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.IGraphicsTarget; +import com.raytheon.uf.viz.core.IView; +import com.raytheon.uf.viz.core.drawables.IDescriptor; +import com.raytheon.uf.viz.core.drawables.IRenderableDisplay; +import com.raytheon.uf.viz.core.drawables.ResourcePair; +import com.raytheon.uf.viz.core.exception.VizException; +import com.raytheon.uf.viz.remote.graphics.objects.ViewWrapper; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Graphics factory for creating graphics objects that forward (dispatch) + * important events for remote processing + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 5, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DispatchingGraphicsFactory extends AbstractGraphicsFactoryAdapter { + + private AbstractGraphicsFactoryAdapter delegate; + + private Dispatcher dispatcher; + + private DispatchingGraphicsFactory(AbstractGraphicsFactoryAdapter delegate, + Dispatcher dispatcher) { + this.delegate = delegate; + this.dispatcher = dispatcher; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constructView() + */ + @Override + public IView constructView() { + return new ViewWrapper(delegate.constructView()); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constructTarget + * (org.eclipse.swt.widgets.Canvas, float, float) + */ + @Override + public IGraphicsTarget constructTarget(Canvas canvas, float width, + float height) throws VizException { + return new DispatchGraphicsTarget(delegate.constructTarget(canvas, + width, height), canvas, dispatcher); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constructExtent + * (com.vividsolutions.jts.geom.Coordinate[]) + */ + @Override + public IExtent constructExtent(Coordinate[] coords) throws VizException { + return delegate.constructExtent(coords); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constructExtent + * (double, double, double, double) + */ + @Override + public IExtent constructExtent(double aMinX, double aMaxX, double aMinY, + double aMaxY) throws VizException { + return delegate.constructExtent(aMinX, aMaxX, aMinY, aMaxY); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constructExtent + * (org.eclipse.swt.graphics.Rectangle) + */ + @Override + public IExtent constructExtent(Rectangle rect) throws VizException { + return delegate.constructExtent(rect); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constructExtent + * (org.opengis.coverage.grid.GridEnvelope) + */ + @Override + public IExtent constructExtent(GridEnvelope range) throws VizException { + return delegate.constructExtent(range); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter#constrcutCanvas + * (org.eclipse.swt.widgets.Composite) + */ + @Override + public Canvas constrcutCanvas(Composite canvasComp) throws VizException { + return delegate.constrcutCanvas(canvasComp); + } + + /** + * Injects the DispatchingGraphicsFactory into the given display + * + * @param display + * @param factory + * @throws InstantiationException + */ + public static boolean injectRemoteFunctionality(IDisplayPane pane, + DispatcherFactory factory) throws InstantiationException { + boolean injected = false; + IRenderableDisplay display = pane.getRenderableDisplay(); + AbstractGraphicsFactoryAdapter currAdapter = display + .getGraphicsAdapter(); + if (currAdapter instanceof DispatchingGraphicsFactory == false) { + // Wrap the graphics adapter in dispatching one + display.setGraphicsAdapter(new DispatchingGraphicsFactory( + currAdapter, factory.createNewDispatcher(display))); + refreshPane(pane); + injected = true; + } + return injected; + } + + /** + * Extracts the DispatchingGraphicsFactory from the given renderable display + * + * @param display + */ + public static boolean extractRemoteFunctionality(IDisplayPane pane) { + boolean extracted = false; + IRenderableDisplay display = pane.getRenderableDisplay(); + AbstractGraphicsFactoryAdapter adapter = display.getGraphicsAdapter(); + if (adapter instanceof DispatchingGraphicsFactory) { + AbstractGraphicsFactoryAdapter wrapped = ((DispatchingGraphicsFactory) adapter).delegate; + display.setGraphicsAdapter(wrapped); + refreshPane(pane); + extracted = true; + } + return extracted; + } + + /** + * Refresh the IDisplayPane and recycle the resources on the pane. Should be + * executed after graphics injection + * + * @param pane + */ + private static void refreshPane(IDisplayPane pane) { + IRenderableDisplay display = pane.getRenderableDisplay(); + IDescriptor descriptor = display.getDescriptor(); + // Force resetting of the pane's display + pane.setRenderableDisplay(null); + pane.setRenderableDisplay(display); + + display.setup(pane.getTarget()); + + for (ResourcePair rp : descriptor.getResourceList()) { + if (rp.getResource() != null) { + rp.getResource().recycle(); + } + } + + if (descriptor.getTimeMatcher() != null) { + try { + descriptor.getTimeMatcher().redoTimeMatching(descriptor); + } catch (VizException e) { + Activator.statusHandler.handle(Priority.PROBLEM, + "Error redoing time matching", e); + } + } + + pane.refresh(); + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingObject.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingObject.java new file mode 100644 index 0000000000..497d7a9227 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/DispatchingObject.java @@ -0,0 +1,72 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics; + +import com.raytheon.uf.viz.remote.graphics.events.AbstractRemoteGraphicsEvent; + + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Feb 28, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DispatchingObject { + + private int objectId; + + private Dispatcher dispatcher; + + protected T wrappedObject; + + public DispatchingObject(T targetObject, Dispatcher dispatcher) { + this.wrappedObject = targetObject; + this.dispatcher = dispatcher; + objectId = dispatcher.newObjectId(); + } + + public int getObjectId() { + return objectId; + } + + public T getWrappedObject() { + return wrappedObject; + } + + public Dispatcher getDispatcher() { + return dispatcher; + } + + public void dispatch(AbstractRemoteGraphicsEvent eventObject) { + dispatcher.dispatch(eventObject); + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/PixelExtentSerializationAdapter.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/PixelExtentSerializationAdapter.java new file mode 100644 index 0000000000..168a8e4a5e --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/PixelExtentSerializationAdapter.java @@ -0,0 +1,77 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.adapters; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.viz.core.PixelExtent; + +/** + * Serialization adapter for PixelExtent + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class PixelExtentSerializationAdapter implements + ISerializationTypeAdapter { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#serialize + * (com.raytheon.uf.common.serialization.ISerializationContext, + * java.lang.Object) + */ + @Override + public void serialize(ISerializationContext serializer, PixelExtent object) + throws SerializationException { + serializer.writeDoubleArray(new double[] { object.getMinX(), + object.getMaxX(), object.getMinY(), object.getMaxY() }); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#deserialize + * (com.raytheon.uf.common.serialization.IDeserializationContext) + */ + @Override + public PixelExtent deserialize(IDeserializationContext deserializer) + throws SerializationException { + double[] extent = deserializer.readDoubleArray(); + return new PixelExtent(extent[0], extent[1], extent[2], extent[3]); + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RGBSerializationAdapter.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RGBSerializationAdapter.java new file mode 100644 index 0000000000..0a74ea9723 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RGBSerializationAdapter.java @@ -0,0 +1,78 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.adapters; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; + +/** + * Serialization adapter for RGB + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class RGBSerializationAdapter implements ISerializationTypeAdapter { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#serialize + * (com.raytheon.uf.common.serialization.ISerializationContext, + * java.lang.Object) + */ + @Override + public void serialize(ISerializationContext serializer, RGB object) + throws SerializationException { + serializer.writeI32(object.red); + serializer.writeI32(object.green); + serializer.writeI32(object.blue); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#deserialize + * (com.raytheon.uf.common.serialization.IDeserializationContext) + */ + @Override + public RGB deserialize(IDeserializationContext deserializer) + throws SerializationException { + return new RGB(deserializer.readI32(), deserializer.readI32(), + deserializer.readI32()); + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RectangleAdapter.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RectangleAdapter.java new file mode 100644 index 0000000000..00f057ea2b --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RectangleAdapter.java @@ -0,0 +1,79 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.adapters; + +import org.eclipse.swt.graphics.Rectangle; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; + +/** + * Adapter for swt Rectangle object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 14, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class RectangleAdapter implements ISerializationTypeAdapter { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#serialize + * (com.raytheon.uf.common.serialization.ISerializationContext, + * java.lang.Object) + */ + @Override + public void serialize(ISerializationContext serializer, Rectangle object) + throws SerializationException { + serializer.writeI32(object.x); + serializer.writeI32(object.y); + serializer.writeI32(object.width); + serializer.writeI32(object.height); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#deserialize + * (com.raytheon.uf.common.serialization.IDeserializationContext) + */ + @Override + public Rectangle deserialize(IDeserializationContext deserializer) + throws SerializationException { + return new Rectangle(deserializer.readI32(), deserializer.readI32(), + deserializer.readI32(), deserializer.readI32()); + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RenderedImageAdapter.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RenderedImageAdapter.java new file mode 100644 index 0000000000..9b53616a5f --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/adapters/RenderedImageAdapter.java @@ -0,0 +1,97 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.adapters; + +import java.awt.image.RenderedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.imageio.ImageIO; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; + +/** + * Serialization adapter for RenderedImages + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class RenderedImageAdapter implements + ISerializationTypeAdapter { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#serialize + * (com.raytheon.uf.common.serialization.ISerializationContext, + * java.lang.Object) + */ + @Override + public void serialize(ISerializationContext serializer, RenderedImage image) + throws SerializationException { + // serialize rendered image into bytes + try { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + ImageIO.write(image, "png", bytes); + serializer.writeBinary(bytes.toByteArray()); + } catch (IOException e) { + throw new SerializationException( + "Error serializing rendered image", e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#deserialize + * (com.raytheon.uf.common.serialization.IDeserializationContext) + */ + @Override + public RenderedImage deserialize(IDeserializationContext deserializer) + throws SerializationException { + byte[] data = deserializer.readBinary(); + // deserialize bytes into rendered image + try { + return ImageIO.read(new ByteArrayInputStream(data)); + } catch (Exception e) { + throw new SerializationException( + "Error deserializing rendered image: " + + e.getLocalizedMessage(), e); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractDispatchingObjectEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractDispatchingObjectEvent.java new file mode 100644 index 0000000000..f5f4f74c93 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractDispatchingObjectEvent.java @@ -0,0 +1,90 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public abstract class AbstractDispatchingObjectEvent extends + AbstractRemoteGraphicsEvent { + + @DynamicSerializeElement + private int objectId; + + public AbstractDispatchingObjectEvent() { + + } + + protected AbstractDispatchingObjectEvent(int objectId) { + this.objectId = objectId; + } + + /** + * @return the objectId + */ + public int getObjectId() { + return objectId; + } + + /** + * @param objectId + * the objectId to set + */ + public void setObjectId(int objectId) { + this.objectId = objectId; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AbstractDispatchingObjectEvent other = (AbstractDispatchingObjectEvent) obj; + if (objectId != other.objectId) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java new file mode 100644 index 0000000000..8be02e9065 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/AbstractRemoteGraphicsEvent.java @@ -0,0 +1,62 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public abstract class AbstractRemoteGraphicsEvent { + + @DynamicSerializeElement + private int displayId; + + /** + * @return the displayId + */ + public int getDisplayId() { + return displayId; + } + + /** + * @param displayId + * the displayId to set + */ + public void setDisplayId(int displayId) { + this.displayId = displayId; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/DisposeObjectEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/DisposeObjectEvent.java new file mode 100644 index 0000000000..00a787c214 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/DisposeObjectEvent.java @@ -0,0 +1,43 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DisposeObjectEvent extends AbstractDispatchingObjectEvent { + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/ICreationEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/ICreationEvent.java new file mode 100644 index 0000000000..d9b3a03d40 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/ICreationEvent.java @@ -0,0 +1,41 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events; + +/** + * Interface for object creation events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 20, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface ICreationEvent { + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/RemoteGraphicsEventFactory.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/RemoteGraphicsEventFactory.java new file mode 100644 index 0000000000..6f8f122737 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/RemoteGraphicsEventFactory.java @@ -0,0 +1,59 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events; + +import com.raytheon.uf.viz.remote.graphics.DispatchingObject; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class RemoteGraphicsEventFactory { + + public static T createEvent( + Class eventType, DispatchingObject creatingObject) { + T event = null; + try { + event = eventType.newInstance(); + event.setDisplayId(creatingObject.getDispatcher().getDispatcherId()); + if (AbstractDispatchingObjectEvent.class + .isAssignableFrom(eventType)) { + AbstractDispatchingObjectEvent.class.cast(event).setObjectId( + creatingObject.getObjectId()); + } + } catch (Throwable t) { + // TODO: Handle gracefully + } + return event; + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/clipping/ClearClippingPane.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/clipping/ClearClippingPane.java new file mode 100644 index 0000000000..61efa30670 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/clipping/ClearClippingPane.java @@ -0,0 +1,73 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.clipping; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for clearing the clipping pane + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ClearClippingPane extends AbstractRemoteGraphicsRenderEvent { + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + // Nothing to do + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/clipping/SetupClippingPane.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/clipping/SetupClippingPane.java new file mode 100644 index 0000000000..83aefb5406 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/clipping/SetupClippingPane.java @@ -0,0 +1,120 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.clipping; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for setting up the clipping pane for rendering + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class SetupClippingPane extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private IExtent extent; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + SetupClippingPane diffEvent = (SetupClippingPane) event; + SetupClippingPane diffObject = new SetupClippingPane(); + if (extent.equals(diffEvent.extent) == false) { + diffObject.extent = diffEvent.extent; + } + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + SetupClippingPane diffObject = (SetupClippingPane) diffEvent; + if (diffObject.extent != null) { + extent = diffObject.extent; + } + } + + /** + * @return the extent + */ + public IExtent getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(IExtent extent) { + this.extent = extent; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + SetupClippingPane other = (SetupClippingPane) obj; + if (extent == null) { + if (other.extent != null) + return false; + } else if (!extent.equals(other.extent)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/ColorMapDataEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/ColorMapDataEvent.java new file mode 100644 index 0000000000..a23621adc1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/ColorMapDataEvent.java @@ -0,0 +1,134 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import java.nio.Buffer; + +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.SerializationUtil; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback.ColorMapData; +import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback.ColorMapDataType; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Event for sending ColorMapData, serializes object immediately to avoid + * concurrency issues with other threads using the buffer async + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 9, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ColorMapDataEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private int[] dimensions; + + @DynamicSerializeElement + private ColorMapDataType dataType; + + @DynamicSerializeElement + private Buffer buffer; + + /** + * @return the colorMapData + */ + public ColorMapData getColorMapData() { + return new ColorMapData(buffer, dimensions, dataType); + } + + /** + * @param colorMapData + * the colorMapData to set + */ + public void setColorMapData(ColorMapData colorMapData) { + // Copy data via serialization + this.dimensions = colorMapData.getDimensions(); + this.dataType = colorMapData.getDataType(); + try { + // Copy the buffer since it is the same buffer that will be used for + // rendering in a separate thread and serializing Buffer access is + // not thread safe + this.buffer = (Buffer) SerializationUtil + .transformFromThrift(SerializationUtil + .transformToThrift(colorMapData.getBuffer())); + } catch (SerializationException e) { + throw new RuntimeException("Error copying data Buffer: " + + e.getLocalizedMessage(), e); + } + } + + /** + * @return the dimensions + */ + public int[] getDimensions() { + return dimensions; + } + + /** + * @param dimensions + * the dimensions to set + */ + public void setDimensions(int[] dimensions) { + this.dimensions = dimensions; + } + + /** + * @return the dataType + */ + public ColorMapDataType getDataType() { + return dataType; + } + + /** + * @param dataType + * the dataType to set + */ + public void setDataType(ColorMapDataType dataType) { + this.dataType = dataType; + } + + /** + * @return the buffer + */ + public Buffer getBuffer() { + return buffer; + } + + /** + * @param buffer + * the buffer to set + */ + public void setBuffer(Buffer buffer) { + this.buffer = buffer; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/CreateColorMapEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/CreateColorMapEvent.java new file mode 100644 index 0000000000..58fee82aaa --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/CreateColorMapEvent.java @@ -0,0 +1,132 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import com.raytheon.uf.common.colormap.IColorMap; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Creation event for an IColorMap object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateColorMapEvent extends AbstractDispatchingObjectEvent + implements ICreationEvent { + + @DynamicSerializeElement + private float[] red; + + @DynamicSerializeElement + private float[] blue; + + @DynamicSerializeElement + private float[] green; + + @DynamicSerializeElement + private float[] alpha; + + /** + * @return the red + */ + public float[] getRed() { + return red; + } + + /** + * @param red + * the red to set + */ + public void setRed(float[] red) { + this.red = red; + } + + /** + * @return the blue + */ + public float[] getBlue() { + return blue; + } + + /** + * @param blue + * the blue to set + */ + public void setBlue(float[] blue) { + this.blue = blue; + } + + /** + * @return the green + */ + public float[] getGreen() { + return green; + } + + /** + * @param green + * the green to set + */ + public void setGreen(float[] green) { + this.green = green; + } + + /** + * @return the alpha + */ + public float[] getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(float[] alpha) { + this.alpha = alpha; + } + + public IColorMap getColorMap() { + return UpdateColorMapEvent.createColormap(red, green, blue, alpha); + } + + public void setColorMap(IColorMap colorMap) { + if (colorMap != null) { + red = colorMap.getRed(); + green = colorMap.getGreen(); + blue = colorMap.getBlue(); + alpha = colorMap.getAlpha(); + } + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/CreateColormappedImageEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/CreateColormappedImageEvent.java new file mode 100644 index 0000000000..e74e8f9aa4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/CreateColormappedImageEvent.java @@ -0,0 +1,84 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateColormappedImageEvent extends AbstractDispatchingObjectEvent + implements ICreationEvent { + + @DynamicSerializeElement + private UpdateColorMapParametersEvent colorMapParameters; + + @DynamicSerializeElement + private UpdateColorMapEvent colorMap; + + /** + * @return the colorMapParameters + */ + public UpdateColorMapParametersEvent getColorMapParameters() { + return colorMapParameters; + } + + /** + * @param colorMapParameters + * the colorMapParameters to set + */ + public void setColorMapParameters( + UpdateColorMapParametersEvent colorMapParameters) { + this.colorMapParameters = colorMapParameters; + } + + /** + * @return the colorMap + */ + public UpdateColorMapEvent getColorMap() { + return colorMap; + } + + /** + * @param colorMap + * the colorMap to set + */ + public void setColorMap(UpdateColorMapEvent colorMap) { + this.colorMap = colorMap; + } + +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/DispatchingColorMapManager.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/DispatchingColorMapManager.java new file mode 100644 index 0000000000..89cca4b8e3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/DispatchingColorMapManager.java @@ -0,0 +1,119 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import com.raytheon.uf.common.colormap.IColorMap; +import com.raytheon.uf.viz.core.drawables.ColorMapParameters; +import com.raytheon.uf.viz.remote.graphics.Dispatcher; +import com.raytheon.uf.viz.remote.graphics.DispatchingObject; +import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; + +/** + * Manager class for color maps + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public class DispatchingColorMapManager { + + private static final int MAX_COLOR_MAPS = 10; + + private static Map instanceMap = new HashMap(); + + public static synchronized DispatchingColorMapManager getInstance( + Dispatcher dispatcher) { + DispatchingColorMapManager manager = instanceMap.get(dispatcher + .getDispatcherId()); + if (manager == null) { + manager = new DispatchingColorMapManager(dispatcher); + instanceMap.put(dispatcher.getDispatcherId(), manager); + } + return manager; + } + + private Dispatcher dispatcher; + + private Map> colorMaps = new LinkedHashMap>() { + + private static final long serialVersionUID = 1L; + + /* + * (non-Javadoc) + * + * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) + */ + @Override + protected boolean removeEldestEntry( + Entry> eldest) { + boolean rval = false; + if (size() > MAX_COLOR_MAPS) { + rval = true; + dispatcher.dispatch(RemoteGraphicsEventFactory.createEvent( + DisposeObjectEvent.class, eldest.getValue())); + } + return rval; + } + + }; + + // TODO: Also keep track of ColorMapParameters? So a CMImage would have an + // id to parameters and an id to colormap? or would the parameters have an + // id to a colormap? + + private DispatchingColorMapManager(Dispatcher dispatcher) { + this.dispatcher = dispatcher; + } + + public int getColorMapId(ColorMapParameters parameters) { + IColorMap cmap = parameters.getColorMap(); + String name = cmap.getName(); + if (name == null) { + name = ColorMapParameters.class.toString() + "@" + + parameters.hashCode(); + } + DispatchingObject object = colorMaps.get(name); + if (object == null) { + object = new DispatchingObject(null, dispatcher); + CreateColorMapEvent event = RemoteGraphicsEventFactory.createEvent( + CreateColorMapEvent.class, object); + event.setColorMap(cmap); + dispatcher.dispatch(event); + colorMaps.put(name, object); + } + return object.getObjectId(); + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/DrawColorRampEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/DrawColorRampEvent.java new file mode 100644 index 0000000000..ae6cde51e1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/DrawColorRampEvent.java @@ -0,0 +1,261 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import com.raytheon.uf.common.colormap.IColorMap; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.DrawableColorMap; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for rending a color map + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 3, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawColorRampEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private Integer colorMapId; + + @DynamicSerializeElement + private Float alpha; + + @DynamicSerializeElement + private Float brightness; + + @DynamicSerializeElement + private Float contrast; + + @DynamicSerializeElement + private Boolean interpolate; + + @DynamicSerializeElement + private IExtent extent; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + DrawColorRampEvent diffEvent = (DrawColorRampEvent) event; + DrawColorRampEvent diffObject = new DrawColorRampEvent(); + if (!equals(colorMapId, diffEvent.colorMapId)) + diffObject.colorMapId = diffEvent.colorMapId; + if (!equals(alpha, diffEvent.alpha)) + diffObject.alpha = diffEvent.alpha; + if (!equals(brightness, diffEvent.brightness)) + diffObject.brightness = diffEvent.brightness; + if (!equals(contrast, diffEvent.contrast)) + diffObject.contrast = diffEvent.contrast; + if (!equals(interpolate, diffEvent.interpolate)) + diffObject.interpolate = diffEvent.interpolate; + if (!equals(extent, diffEvent.extent)) + diffObject.extent = diffEvent.extent; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + DrawColorRampEvent diffObject = (DrawColorRampEvent) diffEvent; + if (diffObject.colorMapId != null) + colorMapId = diffObject.colorMapId; + if (diffObject.alpha != null) + alpha = diffObject.alpha; + if (diffObject.brightness != null) + brightness = diffObject.brightness; + if (diffObject.contrast != null) + contrast = diffObject.contrast; + if (diffObject.interpolate != null) + interpolate = diffObject.interpolate; + if (diffObject.extent != null) + extent = diffObject.extent; + } + + public void setDrawableColorMap(DrawableColorMap colorMap, int colorMapId) { + this.colorMapId = colorMapId; + this.alpha = colorMap.alpha; + this.brightness = colorMap.brightness; + this.contrast = colorMap.contrast; + this.interpolate = colorMap.interpolate; + this.extent = colorMap.extent; + } + + public DrawableColorMap getDrawableColorMap(IColorMap cmap) { + DrawableColorMap colorMap = new DrawableColorMap(cmap); + colorMap.alpha = alpha; + colorMap.brightness = brightness; + colorMap.contrast = contrast; + colorMap.interpolate = interpolate; + colorMap.extent = extent; + return colorMap; + } + + /** + * @return the colorMapId + */ + public Integer getColorMapId() { + return colorMapId; + } + + /** + * @param colorMapId + * the colorMapId to set + */ + public void setColorMapId(Integer colorMapId) { + this.colorMapId = colorMapId; + } + + /** + * @return the alpha + */ + public Float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(Float alpha) { + this.alpha = alpha; + } + + /** + * @return the brightness + */ + public Float getBrightness() { + return brightness; + } + + /** + * @param brightness + * the brightness to set + */ + public void setBrightness(Float brightness) { + this.brightness = brightness; + } + + /** + * @return the contrast + */ + public Float getContrast() { + return contrast; + } + + /** + * @param contrast + * the contrast to set + */ + public void setContrast(Float contrast) { + this.contrast = contrast; + } + + /** + * @return the interpolate + */ + public Boolean getInterpolate() { + return interpolate; + } + + /** + * @param interpolate + * the interpolate to set + */ + public void setInterpolate(Boolean interpolate) { + this.interpolate = interpolate; + } + + /** + * @return the extent + */ + public IExtent getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(IExtent extent) { + this.extent = extent; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DrawColorRampEvent other = (DrawColorRampEvent) obj; + if (Float.floatToIntBits(alpha) != Float.floatToIntBits(other.alpha)) + return false; + if (Float.floatToIntBits(brightness) != Float + .floatToIntBits(other.brightness)) + return false; + if (colorMapId != other.colorMapId) + return false; + if (Float.floatToIntBits(contrast) != Float + .floatToIntBits(other.contrast)) + return false; + if (extent == null) { + if (other.extent != null) + return false; + } else if (!extent.equals(other.extent)) + return false; + if (interpolate != other.interpolate) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/UpdateColorMapEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/UpdateColorMapEvent.java new file mode 100644 index 0000000000..ba12b362fa --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/UpdateColorMapEvent.java @@ -0,0 +1,180 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import java.util.Arrays; + +import com.raytheon.uf.common.colormap.ColorMap; +import com.raytheon.uf.common.colormap.IColorMap; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.objects.AbstractDispatchingImage; + +/** + * Event for updating the IColorMap on an IColormappedImage + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 25, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateColorMapEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private float[] red; + + @DynamicSerializeElement + private float[] blue; + + @DynamicSerializeElement + private float[] green; + + @DynamicSerializeElement + private float[] alpha; + + /** + * @return the red + */ + public float[] getRed() { + return red; + } + + /** + * @param red + * the red to set + */ + public void setRed(float[] red) { + this.red = red; + } + + /** + * @return the blue + */ + public float[] getBlue() { + return blue; + } + + /** + * @param blue + * the blue to set + */ + public void setBlue(float[] blue) { + this.blue = blue; + } + + /** + * @return the green + */ + public float[] getGreen() { + return green; + } + + /** + * @param green + * the green to set + */ + public void setGreen(float[] green) { + this.green = green; + } + + /** + * @return the alpha + */ + public float[] getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(float[] alpha) { + this.alpha = alpha; + } + + public IColorMap getColorMap() { + return createColormap(red, green, blue, alpha); + } + + public void setColorMap(IColorMap colorMap) { + if (colorMap != null) { + red = colorMap.getRed(); + green = colorMap.getGreen(); + blue = colorMap.getBlue(); + alpha = colorMap.getAlpha(); + } + } + + /** + * @param wrapper + * @param parameters + * @return + */ + public static UpdateColorMapEvent createEvent( + AbstractDispatchingImage wrapper, IColorMap colorMap) { + UpdateColorMapEvent event = RemoteGraphicsEventFactory.createEvent( + UpdateColorMapEvent.class, wrapper); + event.setColorMap(colorMap); + return event; + } + + /** + * Given the component colros creates a colormap with a unique name. + * + * @param red + * @param green + * @param blue + * @param alpha + * @return + */ + public static ColorMap createColormap(float[] red, float[] green, + float[] blue, float[] alpha) { + ColorMap colorMap = null; + if (red != null && green != null && blue != null && alpha != null) { + // The target may be caching colormaps based off the name so make + // the name as unique as possible, we do not want to use the same + // name as the data provider because we may have a local colormap + // with the same name but different colors. + StringBuilder colorMapName = new StringBuilder("remoteColormap"); + colorMapName.append("-red="); + colorMapName.append(Arrays.hashCode(red)); + colorMapName.append("-green="); + colorMapName.append(Arrays.hashCode(green)); + colorMapName.append("-blue="); + colorMapName.append(Arrays.hashCode(blue)); + colorMapName.append("-alpha="); + colorMapName.append(Arrays.hashCode(alpha)); + colorMap = new ColorMap(colorMapName.toString(), red, green, blue, + alpha); + } + return colorMap; + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/UpdateColorMapParametersEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/UpdateColorMapParametersEvent.java new file mode 100644 index 0000000000..e46592af8f --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/colormap/UpdateColorMapParametersEvent.java @@ -0,0 +1,262 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.colormap; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.drawables.ColorMapParameters; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.objects.AbstractDispatchingImage; + +/** + * Event for updating the ColorMapParameters on an IColormappedImage + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateColorMapParametersEvent extends + AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private byte[] alphaMask; + + @DynamicSerializeElement + private float colorMapMax; + + @DynamicSerializeElement + private float colorMapMin; + + @DynamicSerializeElement + private float dataMax; + + @DynamicSerializeElement + private float dataMin; + + @DynamicSerializeElement + private boolean logarithmic; + + @DynamicSerializeElement + private float logFactor; + + @DynamicSerializeElement + private boolean mirror; + + @DynamicSerializeElement + private boolean useMask; + + /** + * @return the alphaMask + */ + public byte[] getAlphaMask() { + return alphaMask; + } + + /** + * @param alphaMask + * the alphaMask to set + */ + public void setAlphaMask(byte[] alphaMask) { + this.alphaMask = alphaMask; + } + + /** + * @return the colorMapMax + */ + public float getColorMapMax() { + return colorMapMax; + } + + /** + * @param colorMapMax + * the colorMapMax to set + */ + public void setColorMapMax(float colorMapMax) { + this.colorMapMax = colorMapMax; + } + + /** + * @return the colorMapMin + */ + public float getColorMapMin() { + return colorMapMin; + } + + /** + * @param colorMapMin + * the colorMapMin to set + */ + public void setColorMapMin(float colorMapMin) { + this.colorMapMin = colorMapMin; + } + + /** + * @return the dataMax + */ + public float getDataMax() { + return dataMax; + } + + /** + * @param dataMax + * the dataMax to set + */ + public void setDataMax(float dataMax) { + this.dataMax = dataMax; + } + + /** + * @return the dataMin + */ + public float getDataMin() { + return dataMin; + } + + /** + * @param dataMin + * the dataMin to set + */ + public void setDataMin(float dataMin) { + this.dataMin = dataMin; + } + + /** + * @return the logarithmic + */ + public boolean isLogarithmic() { + return logarithmic; + } + + /** + * @param logarithmic + * the logarithmic to set + */ + public void setLogarithmic(boolean logarithmic) { + this.logarithmic = logarithmic; + } + + /** + * @return the logFactor + */ + public float getLogFactor() { + return logFactor; + } + + /** + * @param logFactor + * the logFactor to set + */ + public void setLogFactor(float logFactor) { + this.logFactor = logFactor; + } + + /** + * @return the mirror + */ + public boolean isMirror() { + return mirror; + } + + /** + * @param mirror + * the mirror to set + */ + public void setMirror(boolean mirror) { + this.mirror = mirror; + } + + /** + * @return the useMask + */ + public boolean isUseMask() { + return useMask; + } + + /** + * @param useMask + * the useMask to set + */ + public void setUseMask(boolean useMask) { + this.useMask = useMask; + } + + /** + * Set the ColorMapParameters for the event + * + * @param parameters + */ + public void setColorMapParameters(ColorMapParameters parameters) { + if (parameters != null) { + setAlphaMask(parameters.getAlphaMask()); + setColorMapMin(parameters.getColorMapMin()); + setColorMapMax(parameters.getColorMapMax()); + setDataMin(parameters.getDataMin()); + setDataMax(parameters.getDataMax()); + setLogarithmic(parameters.isLogarithmic()); + setLogFactor(parameters.getLogFactor()); + setMirror(parameters.isMirror()); + setUseMask(parameters.isUseMask()); + } + } + + /** + * Get the update colormap parameters event as ColorMapParameters object + * + * @return + */ + public ColorMapParameters getColorMapParameters() { + ColorMapParameters params = new ColorMapParameters(); + params.setAlphaMask(getAlphaMask()); + params.setColorMapMin(getColorMapMin()); + params.setColorMapMax(getColorMapMax()); + params.setDataMin(getDataMin()); + params.setDataMax(getDataMax()); + params.setLogarithmic(isLogarithmic()); + params.setLogFactor(getLogFactor()); + params.setMirror(isMirror()); + params.setUseMask(isUseMask()); + return params; + } + + /** + * @param wrapper + * @param parameters + * @return + */ + public static UpdateColorMapParametersEvent createEvent( + AbstractDispatchingImage wrapper, ColorMapParameters parameters) { + UpdateColorMapParametersEvent event = RemoteGraphicsEventFactory + .createEvent(UpdateColorMapParametersEvent.class, wrapper); + event.setColorMapParameters(parameters); + return event; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawCircleEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawCircleEvent.java new file mode 100644 index 0000000000..9c9d84310a --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawCircleEvent.java @@ -0,0 +1,480 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.drawables; + +import java.util.Arrays; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.DrawableCircle; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for drawing a circle + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawCircleEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private double[] location; + + @DynamicSerializeElement + private RGB color; + + @DynamicSerializeElement + private Double screenRadius; + + @DynamicSerializeElement + private Double radius; + + @DynamicSerializeElement + private Boolean filled; + + @DynamicSerializeElement + private Boolean includeSides; + + @DynamicSerializeElement + private Integer numberOfPoints; + + @DynamicSerializeElement + private Float startAzimuth; + + @DynamicSerializeElement + private Float endAzimuth; + + @DynamicSerializeElement + private Float lineWidth; + + @DynamicSerializeElement + private LineStyle lineStyle; + + @DynamicSerializeElement + private Float alpha; + + @DynamicSerializeElement + private Boolean xorColors; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public DrawCircleEvent createDiffObject(IRenderEvent event) { + DrawCircleEvent diffEvent = (DrawCircleEvent) event; + DrawCircleEvent diffObject = new DrawCircleEvent(); + if (Arrays.equals(location, diffEvent.location) == false) + diffObject.location = diffEvent.location; + if (!equals(color, diffObject.color)) + diffObject.color = diffEvent.color; + if (!equals(alpha, diffObject.alpha)) + diffObject.alpha = diffEvent.alpha; + if (!equals(xorColors, diffObject.xorColors)) + diffObject.xorColors = diffEvent.xorColors; + if (!equals(filled, diffObject.filled)) + diffObject.filled = diffEvent.filled; + if (!equals(startAzimuth, diffObject.startAzimuth)) + diffObject.startAzimuth = diffEvent.startAzimuth; + if (!equals(endAzimuth, diffObject.endAzimuth)) + diffObject.endAzimuth = diffEvent.endAzimuth; + if (!equals(numberOfPoints, diffObject.numberOfPoints)) + diffObject.numberOfPoints = diffEvent.numberOfPoints; + if (!equals(radius, diffObject.radius)) + diffObject.radius = diffEvent.radius; + if (!equals(screenRadius, diffEvent.screenRadius)) + diffObject.screenRadius = diffEvent.screenRadius; + if (!equals(lineStyle, diffObject.lineStyle)) + diffObject.lineStyle = diffEvent.lineStyle; + if (!equals(lineWidth, diffObject.lineWidth)) + diffObject.lineWidth = diffEvent.lineWidth; + if (!equals(includeSides, diffObject.includeSides)) + diffObject.includeSides = diffEvent.includeSides; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + DrawCircleEvent o = (DrawCircleEvent) diffEvent; + if (o.location != null) + location = o.location; + if (o.color != null) + color = o.color; + if (o.alpha != null) + alpha = o.alpha; + if (o.xorColors != null) + xorColors = o.xorColors; + if (o.filled != null) + filled = o.filled; + if (o.startAzimuth != null) + startAzimuth = o.startAzimuth; + if (o.endAzimuth != null) + endAzimuth = o.endAzimuth; + if (o.numberOfPoints != null) + numberOfPoints = o.numberOfPoints; + if (o.lineStyle != null) + lineStyle = o.lineStyle; + if (o.lineWidth != null) + lineWidth = o.lineWidth; + if (o.includeSides != null) { + includeSides = o.includeSides; + } + if (o.radius != null) { + radius = o.radius; + screenRadius = null; + } else if (o.screenRadius != null) { + screenRadius = o.screenRadius; + radius = null; + } + } + + public void setDrawableCircle(DrawableCircle circle) { + this.location = new double[] { circle.basics.x, circle.basics.y, + circle.basics.z }; + this.color = circle.basics.color; + this.alpha = circle.basics.alpha; + this.xorColors = circle.basics.xOrColors; + this.filled = circle.filled; + this.startAzimuth = circle.startAzimuth; + this.endAzimuth = circle.endAzimuth; + this.numberOfPoints = circle.numberOfPoints; + this.radius = circle.radius; + this.screenRadius = circle.screenRadius; + this.lineStyle = circle.lineStyle; + this.lineWidth = circle.lineWidth; + this.includeSides = circle.includeSides; + } + + public DrawableCircle getDrawableCircle() { + DrawableCircle circle = new DrawableCircle(); + circle.setCoordinates(location[0], location[1], location[2]); + circle.basics.color = color; + circle.basics.alpha = alpha; + circle.basics.xOrColors = xorColors; + circle.filled = filled; + circle.startAzimuth = startAzimuth; + circle.endAzimuth = endAzimuth; + circle.numberOfPoints = numberOfPoints; + circle.radius = radius; + circle.screenRadius = screenRadius; + circle.lineStyle = lineStyle; + circle.lineWidth = lineWidth; + circle.includeSides = includeSides; + return circle; + } + + /** + * @return the location + */ + public double[] getLocation() { + return location; + } + + /** + * @param location + * the location to set + */ + public void setLocation(double[] location) { + this.location = location; + } + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /** + * @return the screenRadius + */ + public Double getScreenRadius() { + return screenRadius; + } + + /** + * @param screenRadius + * the screenRadius to set + */ + public void setScreenRadius(Double screenRadius) { + this.screenRadius = screenRadius; + } + + /** + * @return the radius + */ + public Double getRadius() { + return radius; + } + + /** + * @param radius + * the radius to set + */ + public void setRadius(Double radius) { + this.radius = radius; + } + + /** + * @return the filled + */ + public Boolean getFilled() { + return filled; + } + + /** + * @param filled + * the filled to set + */ + public void setFilled(Boolean filled) { + this.filled = filled; + } + + /** + * @return the includeSides + */ + public Boolean getIncludeSides() { + return includeSides; + } + + /** + * @param includeSides + * the includeSides to set + */ + public void setIncludeSides(Boolean includeSides) { + this.includeSides = includeSides; + } + + /** + * @return the numberOfPoints + */ + public Integer getNumberOfPoints() { + return numberOfPoints; + } + + /** + * @param numberOfPoints + * the numberOfPoints to set + */ + public void setNumberOfPoints(Integer numberOfPoints) { + this.numberOfPoints = numberOfPoints; + } + + /** + * @return the startAzimuth + */ + public Float getStartAzimuth() { + return startAzimuth; + } + + /** + * @param startAzimuth + * the startAzimuth to set + */ + public void setStartAzimuth(Float startAzimuth) { + this.startAzimuth = startAzimuth; + } + + /** + * @return the endAzimuth + */ + public Float getEndAzimuth() { + return endAzimuth; + } + + /** + * @param endAzimuth + * the endAzimuth to set + */ + public void setEndAzimuth(Float endAzimuth) { + this.endAzimuth = endAzimuth; + } + + /** + * @return the lineWidth + */ + public Float getLineWidth() { + return lineWidth; + } + + /** + * @param lineWidth + * the lineWidth to set + */ + public void setLineWidth(Float lineWidth) { + this.lineWidth = lineWidth; + } + + /** + * @return the lineStyle + */ + public LineStyle getLineStyle() { + return lineStyle; + } + + /** + * @param lineStyle + * the lineStyle to set + */ + public void setLineStyle(LineStyle lineStyle) { + this.lineStyle = lineStyle; + } + + /** + * @return the alpha + */ + public Float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(Float alpha) { + this.alpha = alpha; + } + + /** + * @return the xorColors + */ + public Boolean getXorColors() { + return xorColors; + } + + /** + * @param xorColors + * the xorColors to set + */ + public void setXorColors(Boolean xorColors) { + this.xorColors = xorColors; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DrawCircleEvent other = (DrawCircleEvent) obj; + if (alpha == null) { + if (other.alpha != null) + return false; + } else if (!alpha.equals(other.alpha)) + return false; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (endAzimuth == null) { + if (other.endAzimuth != null) + return false; + } else if (!endAzimuth.equals(other.endAzimuth)) + return false; + if (filled == null) { + if (other.filled != null) + return false; + } else if (!filled.equals(other.filled)) + return false; + if (includeSides == null) { + if (other.includeSides != null) + return false; + } else if (!includeSides.equals(other.includeSides)) + return false; + if (lineStyle != other.lineStyle) + return false; + if (lineWidth == null) { + if (other.lineWidth != null) + return false; + } else if (!lineWidth.equals(other.lineWidth)) + return false; + if (!Arrays.equals(location, other.location)) + return false; + if (numberOfPoints == null) { + if (other.numberOfPoints != null) + return false; + } else if (!numberOfPoints.equals(other.numberOfPoints)) + return false; + if (radius == null) { + if (other.radius != null) + return false; + } else if (!radius.equals(other.radius)) + return false; + if (screenRadius == null) { + if (other.screenRadius != null) + return false; + } else if (!screenRadius.equals(other.screenRadius)) + return false; + if (startAzimuth == null) { + if (other.startAzimuth != null) + return false; + } else if (!startAzimuth.equals(other.startAzimuth)) + return false; + if (xorColors == null) { + if (other.xorColors != null) + return false; + } else if (!xorColors.equals(other.xorColors)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawCirclesEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawCirclesEvent.java new file mode 100644 index 0000000000..3c23e8d8b7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawCirclesEvent.java @@ -0,0 +1,56 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.drawables; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsBulkRenderEvent; + +/** + * Event for drawing a series of circles + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawCirclesEvent extends + AbstractRemoteGraphicsBulkRenderEvent { + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent#getObjectClass() + */ + @Override + protected Class getObjectClass() { + return DrawCircleEvent.class; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawLineEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawLineEvent.java new file mode 100644 index 0000000000..a91d0516d5 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawLineEvent.java @@ -0,0 +1,310 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.drawables; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.DrawableLine; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.remote.graphics.events.points.Point; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * DrawableLine event object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawLineEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private List points; + + @DynamicSerializeElement + private LineStyle lineStyle; + + @DynamicSerializeElement + private Float width; + + @DynamicSerializeElement + private RGB color; + + @DynamicSerializeElement + private Float alpha; + + @DynamicSerializeElement + private Boolean xorColors; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + DrawLineEvent diffEvent = (DrawLineEvent) event; + DrawLineEvent diffObject = new DrawLineEvent(); + if (!equals(points, diffEvent.points)) { + List newPoints = new ArrayList( + diffEvent.points.size()); + int diffSize = diffEvent.points.size(); + int mySize = points.size(); + for (int i = 0; i < diffSize; ++i) { + Point diffPoint = diffEvent.points.get(i); + if (i < mySize && points.get(i).equals(diffPoint)) { + diffPoint = null; + } else { + System.out.println("NEW POINT!"); + } + newPoints.add(diffPoint); + } + System.out.println(); + diffObject.points = newPoints; + } + if (!equals(lineStyle, diffEvent.lineStyle)) + diffObject.lineStyle = diffEvent.lineStyle; + if (!equals(width, diffEvent.width)) + diffObject.width = diffEvent.width; + if (!equals(alpha, diffEvent.alpha)) + diffObject.alpha = diffEvent.alpha; + if (!equals(color, diffEvent.color)) + diffObject.color = diffEvent.color; + if (!equals(xorColors, diffEvent.xorColors)) + diffObject.xorColors = diffEvent.xorColors; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + DrawLineEvent diffObject = (DrawLineEvent) diffEvent; + if (diffObject.points != null) { + List newPoints = new ArrayList( + diffObject.points.size()); + int i = 0; + for (Point p : diffObject.points) { + if (p == null) { + p = points.get(i); + } + newPoints.add(p); + ++i; + } + points = newPoints; + } + if (diffObject.lineStyle != null) + lineStyle = diffObject.lineStyle; + if (diffObject.width != null) + width = diffObject.width; + if (diffObject.alpha != null) + alpha = diffObject.alpha; + if (diffObject.color != null) + color = diffObject.color; + if (diffObject.xorColors != null) + xorColors = diffObject.xorColors; + } + + public void setDrawableLine(DrawableLine line) { + points = new ArrayList(line.points.size()); + for (double[] point : line.points) { + Point p = new Point(); + p.setPoint(point); + points.add(p); + } + lineStyle = line.lineStyle; + width = line.width; + alpha = line.basics.alpha; + color = line.basics.color; + xorColors = line.basics.xOrColors; + } + + public DrawableLine getDrawableLine() { + DrawableLine line = new DrawableLine(); + for (Point p : points) { + line.points.add(p.getPoint()); + } + line.lineStyle = lineStyle; + line.width = width; + line.basics.alpha = alpha; + line.basics.color = color; + line.basics.xOrColors = xorColors; + return line; + } + + /** + * @return the points + */ + public List getPoints() { + return points; + } + + /** + * @param points + * the points to set + */ + public void setPoints(List points) { + this.points = points; + } + + /** + * @return the lineStyle + */ + public LineStyle getLineStyle() { + return lineStyle; + } + + /** + * @param lineStyle + * the lineStyle to set + */ + public void setLineStyle(LineStyle lineStyle) { + this.lineStyle = lineStyle; + } + + /** + * @return the width + */ + public Float getWidth() { + return width; + } + + /** + * @param width + * the width to set + */ + public void setWidth(Float width) { + this.width = width; + } + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /** + * @return the alpha + */ + public Float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(Float alpha) { + this.alpha = alpha; + } + + /** + * @return the xorColors + */ + public Boolean getXorColors() { + return xorColors; + } + + /** + * @param xorColors + * the xorColors to set + */ + public void setXorColors(Boolean xorColors) { + this.xorColors = xorColors; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DrawLineEvent other = (DrawLineEvent) obj; + if (alpha == null) { + if (other.alpha != null) + return false; + } else if (!alpha.equals(other.alpha)) + return false; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (lineStyle != other.lineStyle) + return false; + if (points == null) { + if (other.points != null) + return false; + } else if (!points.equals(other.points)) + return false; + if (width == null) { + if (other.width != null) + return false; + } else if (!width.equals(other.width)) + return false; + if (xorColors == null) { + if (other.xorColors != null) + return false; + } else if (!xorColors.equals(other.xorColors)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawLinesEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawLinesEvent.java new file mode 100644 index 0000000000..e248e58d4f --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawLinesEvent.java @@ -0,0 +1,56 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.drawables; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsBulkRenderEvent; + +/** + * Bulk rendering method for lines + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawLinesEvent extends + AbstractRemoteGraphicsBulkRenderEvent { + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent#getObjectClass() + */ + @Override + protected Class getObjectClass() { + return DrawLineEvent.class; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawRectEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawRectEvent.java new file mode 100644 index 0000000000..fa1b350a9a --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/drawables/DrawRectEvent.java @@ -0,0 +1,254 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.drawables; + +import java.util.Arrays; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawRectEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private IExtent extent; + + @DynamicSerializeElement + private RGB color; + + @DynamicSerializeElement + private Float alpha; + + @DynamicSerializeElement + private Float lineWidth; + + @DynamicSerializeElement + private Boolean filled; + + @DynamicSerializeElement + private byte[] fillPattern; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + DrawRectEvent diffEvent = (DrawRectEvent) event; + DrawRectEvent diffObject = new DrawRectEvent(); + if (!equals(alpha, diffEvent.alpha)) + diffObject.alpha = diffEvent.alpha; + if (!equals(color, diffEvent.color)) + diffObject.color = diffEvent.color; + if (!equals(extent, diffEvent.extent)) + diffObject.extent = diffEvent.extent; + if (!equals(filled, diffEvent.filled)) + diffObject.filled = diffEvent.filled; + if (!equals(fillPattern, diffEvent.fillPattern)) + diffObject.fillPattern = diffEvent.fillPattern; + if (!equals(lineWidth, diffEvent.lineWidth)) + diffObject.lineWidth = diffEvent.lineWidth; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + DrawRectEvent diffObject = (DrawRectEvent) diffEvent; + if (diffObject.alpha != null) + alpha = diffObject.alpha; + if (diffObject.color != null) + color = diffObject.color; + if (diffObject.extent != null) + extent = diffObject.extent; + if (diffObject.filled != null) + filled = diffObject.filled; + if (diffObject.fillPattern != null) + fillPattern = diffObject.fillPattern; + if (diffObject.lineWidth != null) + lineWidth = diffObject.lineWidth; + } + + /** + * @return the extent + */ + public IExtent getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(IExtent extent) { + this.extent = extent; + } + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /** + * @return the alpha + */ + public Float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(Float alpha) { + this.alpha = alpha; + } + + /** + * @return the lineWidth + */ + public Float getLineWidth() { + return lineWidth; + } + + /** + * @param lineWidth + * the lineWidth to set + */ + public void setLineWidth(Float lineWidth) { + this.lineWidth = lineWidth; + } + + /** + * @return the filled + */ + public Boolean getFilled() { + return filled; + } + + /** + * @param filled + * the filled to set + */ + public void setFilled(Boolean filled) { + this.filled = filled; + } + + /** + * @return the fillPattern + */ + public byte[] getFillPattern() { + return fillPattern; + } + + /** + * @param fillPattern + * the fillPattern to set + */ + public void setFillPattern(byte[] fillPattern) { + this.fillPattern = fillPattern; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DrawRectEvent other = (DrawRectEvent) obj; + if (alpha == null) { + if (other.alpha != null) + return false; + } else if (!alpha.equals(other.alpha)) + return false; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (extent == null) { + if (other.extent != null) + return false; + } else if (!extent.equals(other.extent)) + return false; + if (!Arrays.equals(fillPattern, other.fillPattern)) + return false; + if (filled == null) { + if (other.filled != null) + return false; + } else if (!filled.equals(other.filled)) + return false; + if (lineWidth == null) { + if (other.lineWidth != null) + return false; + } else if (!lineWidth.equals(other.lineWidth)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/fonts/CreateFontEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/fonts/CreateFontEvent.java new file mode 100644 index 0000000000..6307613ecb --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/fonts/CreateFontEvent.java @@ -0,0 +1,174 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.fonts; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.drawables.IFont.Style; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Event for creating a font object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 12, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateFontEvent extends AbstractDispatchingObjectEvent implements + ICreationEvent { + + @DynamicSerializeElement + private byte[] fontData; + + @DynamicSerializeElement + private String fontName; + + @DynamicSerializeElement + private Style[] fontStyle; + + @DynamicSerializeElement + private float fontSize; + + @DynamicSerializeElement + private float magnification; + + @DynamicSerializeElement + private boolean smoothing; + + @DynamicSerializeElement + private boolean scaleFont; + + /** + * @return the fontData + */ + public byte[] getFontData() { + return fontData; + } + + /** + * @param fontData + * the fontData to set + */ + public void setFontData(byte[] fontData) { + this.fontData = fontData; + } + + /** + * @return the fontName + */ + public String getFontName() { + return fontName; + } + + /** + * @param fontName + * the fontName to set + */ + public void setFontName(String fontName) { + this.fontName = fontName; + } + + /** + * @return the fontStyle + */ + public Style[] getFontStyle() { + return fontStyle; + } + + /** + * @param fontStyle + * the fontStyle to set + */ + public void setFontStyle(Style[] fontStyle) { + this.fontStyle = fontStyle; + } + + /** + * @return the fontSize + */ + public float getFontSize() { + return fontSize; + } + + /** + * @param fontSize + * the fontSize to set + */ + public void setFontSize(float fontSize) { + this.fontSize = fontSize; + } + + /** + * @return the magnification + */ + public float getMagnification() { + return magnification; + } + + /** + * @param magnification + * the magnification to set + */ + public void setMagnification(float magnification) { + this.magnification = magnification; + } + + /** + * @return the smoothing + */ + public boolean isSmoothing() { + return smoothing; + } + + /** + * @param smoothing + * the smoothing to set + */ + public void setSmoothing(boolean smoothing) { + this.smoothing = smoothing; + } + + /** + * @return the scaleFont + */ + public boolean isScaleFont() { + return scaleFont; + } + + /** + * @param scaleFont + * the scaleFont to set + */ + public void setScaleFont(boolean scaleFont) { + this.scaleFont = scaleFont; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/fonts/UpdateFontDataEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/fonts/UpdateFontDataEvent.java new file mode 100644 index 0000000000..8fe74cc692 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/fonts/UpdateFontDataEvent.java @@ -0,0 +1,117 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.fonts; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Event for updating a font object's magnification, smoothing, or scaling + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 12, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateFontDataEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private float magnification; + + @DynamicSerializeElement + private Boolean scaleOnMagnify; + + @DynamicSerializeElement + private boolean smoothing; + + @DynamicSerializeElement + private boolean scaleFont; + + /** + * @return the magnification + */ + public float getMagnification() { + return magnification; + } + + /** + * @param magnification + * the magnification to set + */ + public void setMagnification(float magnification) { + this.magnification = magnification; + } + + /** + * @return the scaleOnMagnify + */ + public Boolean getScaleOnMagnify() { + return scaleOnMagnify; + } + + /** + * @param scaleOnMagnify + * the scaleOnMagnify to set + */ + public void setScaleOnMagnify(Boolean scaleOnMagnify) { + this.scaleOnMagnify = scaleOnMagnify; + } + + /** + * @return the smoothing + */ + public boolean getSmoothing() { + return smoothing; + } + + /** + * @param smoothing + * the smoothing to set + */ + public void setSmoothing(boolean smoothing) { + this.smoothing = smoothing; + } + + /** + * @return the scaleFont + */ + public boolean getScaleFont() { + return scaleFont; + } + + /** + * @param scaleFont + * the scaleFont to set + */ + public void setScaleFont(boolean scaleFont) { + this.scaleFont = scaleFont; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/CreateIImageEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/CreateIImageEvent.java new file mode 100644 index 0000000000..6fe8330d26 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/CreateIImageEvent.java @@ -0,0 +1,46 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Event for creating an IImage object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 19, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateIImageEvent extends AbstractDispatchingObjectEvent implements + ICreationEvent { + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/CreateSingleColorImage.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/CreateSingleColorImage.java new file mode 100644 index 0000000000..862fe8789b --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/CreateSingleColorImage.java @@ -0,0 +1,45 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 13, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateSingleColorImage extends UpdateSingleColorImage implements + ICreationEvent { + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/PaintImageEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/PaintImageEvent.java new file mode 100644 index 0000000000..0974da49b6 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/PaintImageEvent.java @@ -0,0 +1,258 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.PixelCoverage; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class PaintImageEvent extends AbstractDispatchingObjectEvent implements + IRenderEvent { + + @DynamicSerializeElement + private int meshId = -1; + + @DynamicSerializeElement + private Coordinate ul; + + @DynamicSerializeElement + private Coordinate ur; + + @DynamicSerializeElement + private Coordinate lr; + + @DynamicSerializeElement + private Coordinate ll; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#createDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public PaintImageEvent createDiffObject(IRenderEvent event) { + PaintImageEvent diff = (PaintImageEvent) event; + PaintImageEvent diffEvent = new PaintImageEvent(); + diffEvent.setObjectId(diff.getObjectId()); + diffEvent.meshId = diff.meshId; + if (ll != null && ll.equals(diff.ll) == false) { + diffEvent.ll = diff.ll; + } + if (ul != null && ul.equals(diff.ul) == false) { + diffEvent.ul = diff.ul; + } + if (lr != null && lr.equals(diff.lr) == false) { + diffEvent.lr = diff.lr; + } + if (ur != null && ur.equals(diff.ur) == false) { + diffEvent.ur = diff.ur; + } + return diffEvent; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + PaintImageEvent event = (PaintImageEvent) diffEvent; + setObjectId(event.getObjectId()); + meshId = event.meshId; + if (event.ll != null) { + ll = event.ll; + } + if (event.lr != null) { + lr = event.lr; + } + if (event.ul != null) { + ul = event.ul; + } + if (event.ur != null) { + ur = event.ur; + } + } + + /** + * @return the meshId + */ + public int getMeshId() { + return meshId; + } + + /** + * @param meshId + * the meshId to set + */ + public void setMeshId(int meshId) { + this.meshId = meshId; + } + + /** + * @return the ul + */ + public Coordinate getUl() { + return ul; + } + + /** + * @param ul + * the ul to set + */ + public void setUl(Coordinate ul) { + this.ul = ul; + } + + /** + * @return the ur + */ + public Coordinate getUr() { + return ur; + } + + /** + * @param ur + * the ur to set + */ + public void setUr(Coordinate ur) { + this.ur = ur; + } + + /** + * @return the lr + */ + public Coordinate getLr() { + return lr; + } + + /** + * @param lr + * the lr to set + */ + public void setLr(Coordinate lr) { + this.lr = lr; + } + + /** + * @return the ll + */ + public Coordinate getLl() { + return ll; + } + + /** + * @param ll + * the ll to set + */ + public void setLl(Coordinate ll) { + this.ll = ll; + } + + public void setPixelCoverage(PixelCoverage coverage) { + this.ll = coverage.getLl(); + this.lr = coverage.getLr(); + this.ur = coverage.getUr(); + this.ul = coverage.getUl(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PaintImageEvent other = (PaintImageEvent) obj; + if (meshId == other.meshId && meshId != -1) { + // If meshes are set, compare them only + return true; + } else if (meshId == other.meshId) { + // Compare extents if no meshes set (-1) + if (ll == null) { + if (other.ll != null) + return false; + } else if (!ll.equals(other.ll)) + return false; + if (lr == null) { + if (other.lr != null) + return false; + } else if (!lr.equals(other.lr)) + return false; + if (ul == null) { + if (other.ul != null) + return false; + } else if (!ul.equals(other.ul)) + return false; + if (ur == null) { + if (other.ur != null) + return false; + } else if (!ur.equals(other.ur)) + return false; + } + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + @Override + public Object clone() { + PaintImageEvent newInstance = new PaintImageEvent(); + newInstance.applyDiffObject(this); + newInstance.setDisplayId(getDisplayId()); + return newInstance; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/PaintImagesEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/PaintImagesEvent.java new file mode 100644 index 0000000000..a984d6c304 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/PaintImagesEvent.java @@ -0,0 +1,211 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.DrawableImage; +import com.raytheon.uf.viz.core.IMesh; +import com.raytheon.uf.viz.core.PixelCoverage; +import com.raytheon.uf.viz.core.drawables.IImage; +import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsBulkRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; +import com.raytheon.uf.viz.remote.graphics.objects.AbstractDispatchingImage; +import com.raytheon.uf.viz.remote.graphics.objects.DispatchingMesh; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class PaintImagesEvent extends + AbstractRemoteGraphicsBulkRenderEvent { + + @DynamicSerializeElement + private float alpha; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent + * #createDiffObject(com.raytheon.uf.viz + * .remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public PaintImagesEvent createDiffObject(IRenderEvent event) { + PaintImagesEvent diffObject = (PaintImagesEvent) super + .createDiffObject(event); + diffObject.alpha = ((PaintImagesEvent) event).alpha; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent + * #applyDiffObject(com.raytheon.uf.viz. + * remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + super.applyDiffObject(diffEvent); + this.alpha = ((PaintImagesEvent) diffEvent).alpha; + } + + /** + * @return the alpha + */ + public float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(float alpha) { + this.alpha = alpha; + } + + /** + * @param images + * the images to set + */ + public static PaintImageEvent[] toPaintEvents(DrawableImage[] images) { + PaintImageEvent[] imageEvents = new PaintImageEvent[images.length]; + + for (int i = 0; i < images.length; ++i) { + DrawableImage di = images[i]; + AbstractDispatchingImage dispatchingImage = (AbstractDispatchingImage) di + .getImage(); + + // If image parameters have been modified, update + dispatchingImage.updateState(); + + PixelCoverage coverage = di.getCoverage(); + PixelCoverage targetCoverage = new PixelCoverage(coverage.getUl(), + coverage.getUr(), coverage.getLr(), coverage.getLl()); + + PaintImageEvent paintEvent = RemoteGraphicsEventFactory + .createEvent(PaintImageEvent.class, dispatchingImage); + paintEvent.setPixelCoverage(coverage); + + IMesh mesh = coverage.getMesh(); + IMesh targetMesh = null; + if (mesh != null) { + DispatchingMesh dmesh = (DispatchingMesh) mesh; + targetMesh = dmesh.getWrappedObject(); + paintEvent.setMeshId(dmesh.getObjectId()); + targetCoverage.setMesh(targetMesh); + } + + imageEvents[i] = paintEvent; + } + return imageEvents; + } + + /** + * @param images + * the images to set + */ + public static DrawableImage[] extractTargetImages(DrawableImage[] images) { + DrawableImage[] targeted = new DrawableImage[images.length]; + + for (int i = 0; i < images.length; ++i) { + DrawableImage di = images[i]; + AbstractDispatchingImage dispatchingImage = (AbstractDispatchingImage) di + .getImage(); + + IImage targetImage = dispatchingImage.getWrappedObject(); + PixelCoverage coverage = di.getCoverage(); + PixelCoverage targetCoverage = new PixelCoverage(coverage.getUl(), + coverage.getUr(), coverage.getLr(), coverage.getLl()); + + IMesh mesh = coverage.getMesh(); + if (mesh != null) { + DispatchingMesh dmesh = (DispatchingMesh) mesh; + targetCoverage.setMesh(dmesh.getWrappedObject()); + } + + targeted[i] = new DrawableImage(targetImage, targetCoverage, + di.getMode()); + } + return targeted; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent#getObjectClass() + */ + @Override + protected Class getObjectClass() { + return PaintImageEvent.class; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + PaintImagesEvent other = (PaintImagesEvent) obj; + if (Float.floatToIntBits(alpha) != Float.floatToIntBits(other.alpha)) + return false; + return true; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent#clone() + */ + @Override + public Object clone() { + PaintImagesEvent event = (PaintImagesEvent) super.clone(); + event.alpha = alpha; + return event; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/RenderedImageEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/RenderedImageEvent.java new file mode 100644 index 0000000000..d3eb0fc186 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/RenderedImageEvent.java @@ -0,0 +1,66 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import java.awt.image.RenderedImage; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Event that sends a rendered image object for the object id which should be + * treated as an image + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 29, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class RenderedImageEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private RenderedImage renderedImage; + + /** + * @return the renderedImage + */ + public RenderedImage getRenderedImage() { + return renderedImage; + } + + /** + * @param renderedImage + * the renderedImage to set + */ + public void setRenderedImage(RenderedImage renderedImage) { + this.renderedImage = renderedImage; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/UpdateImageDataEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/UpdateImageDataEvent.java new file mode 100644 index 0000000000..578b63ade4 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/UpdateImageDataEvent.java @@ -0,0 +1,99 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateImageDataEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private boolean interpolated = false; + + @DynamicSerializeElement + private float brightness = 1.0f; + + @DynamicSerializeElement + private float contrast = 1.0f; + + /** + * @return the interpolated + */ + public boolean isInterpolated() { + return interpolated; + } + + /** + * @param interpolated + * the interpolated to set + */ + public void setInterpolated(boolean interpolated) { + this.interpolated = interpolated; + } + + /** + * @return the brightness + */ + public float getBrightness() { + return brightness; + } + + /** + * @param brightness + * the brightness to set + */ + public void setBrightness(float brightness) { + this.brightness = brightness; + } + + /** + * @return the contrast + */ + public float getContrast() { + return contrast; + } + + /** + * @param contrast + * the contrast to set + */ + public void setContrast(float contrast) { + this.contrast = contrast; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/UpdateSingleColorImage.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/UpdateSingleColorImage.java new file mode 100644 index 0000000000..6b888c8667 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/imagery/UpdateSingleColorImage.java @@ -0,0 +1,66 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.imagery; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Creates a new single color image with given color or updates a single color + * images color + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 12, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateSingleColorImage extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private RGB color; + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mesh/CreateMeshEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mesh/CreateMeshEvent.java new file mode 100644 index 0000000000..5a65a030b0 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mesh/CreateMeshEvent.java @@ -0,0 +1,86 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.mesh; + +import org.geotools.coverage.grid.GeneralGridGeometry; +import org.geotools.coverage.grid.GridGeometry2D; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateMeshEvent extends AbstractDispatchingObjectEvent implements + ICreationEvent { + + @DynamicSerializeElement + private GridGeometry2D imageGeometry; + + @DynamicSerializeElement + private GeneralGridGeometry targetGeometry; + + /** + * @return the imageGeometry + */ + public GridGeometry2D getImageGeometry() { + return imageGeometry; + } + + /** + * @param imageGeometry + * the imageGeometry to set + */ + public void setImageGeometry(GridGeometry2D imageGeometry) { + this.imageGeometry = imageGeometry; + } + + /** + * @return the targetGeometry + */ + public GeneralGridGeometry getTargetGeometry() { + return targetGeometry; + } + + /** + * @param targetGeometry + * the targetGeometry to set + */ + public void setTargetGeometry(GeneralGridGeometry targetGeometry) { + this.targetGeometry = targetGeometry; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mesh/ReprojectMeshEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mesh/ReprojectMeshEvent.java new file mode 100644 index 0000000000..47dac3dce8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mesh/ReprojectMeshEvent.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.mesh; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ReprojectMeshEvent extends AbstractDispatchingObjectEvent { + + private GeneralGridGeometry targetGeometry; + + /** + * @return the targetGeometry + */ + public GeneralGridGeometry getTargetGeometry() { + return targetGeometry; + } + + /** + * @param targetGeometry + * the targetGeometry to set + */ + public void setTargetGeometry(GeneralGridGeometry targetGeometry) { + this.targetGeometry = targetGeometry; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/CreateMosaicImageEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/CreateMosaicImageEvent.java new file mode 100644 index 0000000000..4504a3c56a --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/CreateMosaicImageEvent.java @@ -0,0 +1,133 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.mosaic; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapEvent; +import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParametersEvent; + +/** + * Event for creating a new mosaic image + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateMosaicImageEvent extends AbstractDispatchingObjectEvent + implements ICreationEvent { + + @DynamicSerializeElement + private String mosaicType; + + @DynamicSerializeElement + private int[] bounds; + + @DynamicSerializeElement + private UpdateMosaicExtent extent; + + @DynamicSerializeElement + private UpdateColorMapParametersEvent colorMapParameters; + + @DynamicSerializeElement + private UpdateColorMapEvent colorMap; + + public String getMosaicType() { + return mosaicType; + } + + public void setMosaicType(String mosaicType) { + this.mosaicType = mosaicType; + } + + /** + * @return the bounds + */ + public int[] getBounds() { + return bounds; + } + + /** + * @param bounds + * the bounds to set + */ + public void setBounds(int[] bounds) { + this.bounds = bounds; + } + + /** + * @return the extent + */ + public UpdateMosaicExtent getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(UpdateMosaicExtent extent) { + this.extent = extent; + } + + /** + * @return the colorMapParameters + */ + public UpdateColorMapParametersEvent getColorMapParameters() { + return colorMapParameters; + } + + /** + * @param colorMapParameters + * the colorMapParameters to set + */ + public void setColorMapParameters( + UpdateColorMapParametersEvent colorMapParameters) { + this.colorMapParameters = colorMapParameters; + } + + /** + * @return the colorMap + */ + public UpdateColorMapEvent getColorMap() { + return colorMap; + } + + /** + * @param colorMap + * the colorMap to set + */ + public void setColorMap(UpdateColorMapEvent colorMap) { + this.colorMap = colorMap; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/UpdateImagesToMosaic.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/UpdateImagesToMosaic.java new file mode 100644 index 0000000000..23204ad38a --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/UpdateImagesToMosaic.java @@ -0,0 +1,64 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.mosaic; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.imagery.PaintImageEvent; + +/** + * Event for updating what images should be in the mosaic + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 16, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateImagesToMosaic extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private PaintImageEvent[] imagesToMosaic; + + /** + * @return the imagesToMosaic + */ + public PaintImageEvent[] getImagesToMosaic() { + return imagesToMosaic; + } + + /** + * @param imagesToMosaic + * the imagesToMosaic to set + */ + public void setImagesToMosaic(PaintImageEvent[] imagesToMosaic) { + this.imagesToMosaic = imagesToMosaic; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/UpdateMosaicExtent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/UpdateMosaicExtent.java new file mode 100644 index 0000000000..59e0bbb443 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/mosaic/UpdateMosaicExtent.java @@ -0,0 +1,64 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.mosaic; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Event object for updating mosaic images extent + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 17, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class UpdateMosaicExtent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private IExtent extent; + + /** + * @return the extent + */ + public IExtent getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(IExtent extent) { + this.extent = extent; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/points/DrawPointsEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/points/DrawPointsEvent.java new file mode 100644 index 0000000000..fce6e799c7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/points/DrawPointsEvent.java @@ -0,0 +1,259 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.points; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IGraphicsTarget.PointStyle; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for specifying the rendering of a collection of points + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 2, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawPointsEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private Set points = new HashSet(); + + @DynamicSerializeElement + private Set removals = null; + + @DynamicSerializeElement + private PointStyle style; + + @DynamicSerializeElement + private float magnification; + + @DynamicSerializeElement + private RGB color; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent diffEvent) { + DrawPointsEvent event = (DrawPointsEvent) diffEvent; + DrawPointsEvent diffObject = new DrawPointsEvent(); + diffObject.color = event.color; + diffObject.magnification = event.magnification; + diffObject.style = event.style; + + Set additions = new HashSet(event.points); + additions.removeAll(points); + Set removals = new HashSet(points); + removals.removeAll(event.points); + if (additions.size() + removals.size() > event.points.size()) { + // Just do a full replace + diffObject.setRemovals(null); + diffObject.setPoints(event.points); + } else { + diffObject.setPoints(additions); + diffObject.setRemovals(removals); + } + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + DrawPointsEvent event = (DrawPointsEvent) diffEvent; + color = event.color; + magnification = event.magnification; + style = event.style; + + synchronized (points) { + if (event.removals != null) { + points.removeAll(event.removals); + points.addAll(event.points); + } else { + points = new HashSet(event.points); + } + } + } + + /** + * @return the points + */ + public Set getPoints() { + return points; + } + + public Collection getPointsCollection() { + synchronized (points) { + List pointList = new ArrayList(points.size()); + for (Point p : points) { + pointList.add(p.getPoint()); + } + return pointList; + } + } + + public void addPoint(double[] point) { + Point p = new Point(); + p.setPoint(point); + this.points.add(p); + } + + public void addPoints(Collection points) { + for (double[] point : points) { + addPoint(point); + } + } + + /** + * @param points + * the points to set + */ + public void setPoints(Set points) { + this.points = points; + } + + /** + * @return the removals + */ + public Set getRemovals() { + return removals; + } + + /** + * @param removals + * the removals to set + */ + public void setRemovals(Set removals) { + this.removals = removals; + } + + /** + * @return the style + */ + public PointStyle getStyle() { + return style; + } + + /** + * @param style + * the style to set + */ + public void setStyle(PointStyle style) { + this.style = style; + } + + /** + * @return the magnification + */ + public float getMagnification() { + return magnification; + } + + /** + * @param magnification + * the magnification to set + */ + public void setMagnification(float magnification) { + this.magnification = magnification; + } + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + DrawPointsEvent other = (DrawPointsEvent) obj; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (Float.floatToIntBits(magnification) != Float + .floatToIntBits(other.magnification)) + return false; + if (points == null) { + if (other.points != null) + return false; + } else if (!points.equals(other.points)) + return false; + if (removals == null) { + if (other.removals != null) + return false; + } else if (!removals.equals(other.removals)) + return false; + if (style != other.style) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/points/Point.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/points/Point.java new file mode 100644 index 0000000000..efdfb602ed --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/points/Point.java @@ -0,0 +1,95 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.points; + +import java.util.Arrays; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Serializable n-dimensional point object with hashCode and equals implemented + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 18, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class Point { + + @DynamicSerializeElement + private double[] point; + + /** + * @return the point + */ + public double[] getPoint() { + return point; + } + + /** + * @param point + * the point to set + */ + public void setPoint(double[] point) { + this.point = point; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + Arrays.hashCode(point); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Point other = (Point) obj; + if (!Arrays.equals(point, other.point)) + return false; + return true; + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/AbstractRemoteGraphicsBulkRenderEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/AbstractRemoteGraphicsBulkRenderEvent.java new file mode 100644 index 0000000000..a3ec33050c --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/AbstractRemoteGraphicsBulkRenderEvent.java @@ -0,0 +1,176 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.rendering; + +import java.lang.reflect.Array; +import java.util.Arrays; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; + +/** + * Abstract class for bulk rendering other objects + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 17, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@SuppressWarnings("unchecked") +@DynamicSerialize +public abstract class AbstractRemoteGraphicsBulkRenderEvent + extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private T[] objects; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#createDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public AbstractRemoteGraphicsBulkRenderEvent createDiffObject( + IRenderEvent event) { + AbstractRemoteGraphicsBulkRenderEvent diff = (AbstractRemoteGraphicsBulkRenderEvent) event; + try { + AbstractRemoteGraphicsBulkRenderEvent diffEvent = (AbstractRemoteGraphicsBulkRenderEvent) event + .getClass().newInstance(); + if (diff.objects != null) { + if (objects != null && diff.objects.length == objects.length) { + diffEvent.objects = (T[]) Array.newInstance( + diff.getObjectClass(), diff.objects.length); + for (int i = 0; i < objects.length; ++i) { + T paintEvent = objects[i]; + T diffPaintEvent = diff.objects[i]; + if (paintEvent.equals(diffPaintEvent) == false) { + diffEvent.objects[i] = (T) paintEvent + .createDiffObject(diffPaintEvent); + } + } + } else { + diffEvent.objects = diff.objects; + } + } + return diffEvent; + } catch (Exception e) { + throw new RuntimeException("Error creating diff object", e); + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + AbstractRemoteGraphicsBulkRenderEvent event = (AbstractRemoteGraphicsBulkRenderEvent) diffEvent; + T[] diffImageEvents = event.objects; + if (diffImageEvents == null) { + objects = null; + } else if (objects == null) { + objects = event.objects; + } else if (objects.length != diffImageEvents.length) { + objects = event.objects; + } else { + for (int i = 0; i < objects.length; ++i) { + T diffPaintEvent = diffImageEvents[i]; + if (diffPaintEvent != null) { + objects[i].applyDiffObject(diffPaintEvent); + } + } + } + } + + /** + * @return the objects + */ + public T[] getObjects() { + return objects; + } + + /** + * @param objects + * the objects to set + */ + public void setObjects(T[] objects) { + this.objects = objects; + } + + protected abstract Class getObjectClass(); + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AbstractRemoteGraphicsBulkRenderEvent other = (AbstractRemoteGraphicsBulkRenderEvent) obj; + if (!Arrays.equals(objects, other.objects)) + return false; + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + @Override + public Object clone() { + try { + AbstractRemoteGraphicsBulkRenderEvent newObject = getClass() + .newInstance(); + if (objects != null) { + newObject.objects = (T[]) Array.newInstance(getObjectClass(), + objects.length); + for (int i = 0; i < objects.length; ++i) { + newObject.objects[i] = (T) objects[i].clone(); + } + } + newObject.setDisplayId(getDisplayId()); + return newObject; + } catch (Exception e) { + throw new RuntimeException("Could not clone " + + getClass().getSimpleName() + " object"); + } + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/AbstractRemoteGraphicsRenderEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/AbstractRemoteGraphicsRenderEvent.java new file mode 100644 index 0000000000..8e5d19052b --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/AbstractRemoteGraphicsRenderEvent.java @@ -0,0 +1,85 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.rendering; + +import com.raytheon.uf.viz.remote.graphics.events.AbstractRemoteGraphicsEvent; + +/** + * Abstract class for non-object based rendering events + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 1, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public abstract class AbstractRemoteGraphicsRenderEvent extends + AbstractRemoteGraphicsEvent implements IRenderEvent { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#createDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + return event; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + @Override + public Object clone() { + try { + AbstractRemoteGraphicsRenderEvent newInstance = getClass() + .newInstance(); + newInstance.applyDiffObject(this); + newInstance.setDisplayId(getDisplayId()); + return newInstance; + } catch (Exception e) { + throw new RuntimeException("Error cloning render event", e); + } + } + + @Override + public abstract boolean equals(Object obj); + + protected static boolean equals(Object one, Object two) { + if (one == two) { + return true; + } else if (one != null && one.equals(two)) { + return true; + } + return false; + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/BeginFrameEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/BeginFrameEvent.java new file mode 100644 index 0000000000..ee7002e901 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/BeginFrameEvent.java @@ -0,0 +1,180 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.rendering; + +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.graphics.Rectangle; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IExtent; + +/** + * Frame that specifies the begining of a new rendering sequence. EndFrameEvent + * signals the end of the rendering sequence + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class BeginFrameEvent extends AbstractRemoteGraphicsRenderEvent { + + @DynamicSerializeElement + private IExtent extent; + + @DynamicSerializeElement + private RGB color; + + @DynamicSerializeElement + private Rectangle bounds; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + BeginFrameEvent diffEvent = (BeginFrameEvent) event; + BeginFrameEvent diffObject = new BeginFrameEvent(); + if (extent.equals(diffEvent.extent) == false) { + diffObject.extent = diffEvent.extent; + } + if (color.equals(diffEvent.color) == false) { + diffObject.color = diffEvent.color; + } + if (bounds.equals(diffEvent.bounds) == false) { + diffObject.bounds = diffEvent.bounds; + } + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + BeginFrameEvent event = (BeginFrameEvent) diffEvent; + if (event.extent != null) { + this.extent = event.extent; + } + if (event.color != null) { + color = event.color; + } + if (event.bounds != null) { + bounds = event.bounds; + } + } + + /** + * @return the extent + */ + public IExtent getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(IExtent extent) { + this.extent = extent; + } + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /** + * @return the bounds + */ + public Rectangle getBounds() { + return bounds; + } + + /** + * @param bounds + * the bounds to set + */ + public void setBounds(Rectangle bounds) { + this.bounds = bounds; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + BeginFrameEvent other = (BeginFrameEvent) obj; + if (bounds == null) { + if (other.bounds != null) + return false; + } else if (!bounds.equals(other.bounds)) + return false; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (extent == null) { + if (other.extent != null) + return false; + } else if (!extent.equals(other.extent)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/EndFrameEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/EndFrameEvent.java new file mode 100644 index 0000000000..6ce248a137 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/EndFrameEvent.java @@ -0,0 +1,71 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.rendering; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 8, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class EndFrameEvent extends AbstractRemoteGraphicsRenderEvent { + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + // Nothing to do + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/IRenderEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/IRenderEvent.java new file mode 100644 index 0000000000..74160314e7 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/rendering/IRenderEvent.java @@ -0,0 +1,51 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.rendering; + +/** + * Interface for objects that events for actually rendering an object. These + * types of events can be skipped over unlike data events which are required to + * execute at some point. Render events must implements equals + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 9, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ + +public interface IRenderEvent { + + @Override + public abstract boolean equals(Object obj); + + public abstract Object clone(); + + public abstract IRenderEvent createDiffObject(IRenderEvent event); + + public abstract void applyDiffObject(IRenderEvent diffEvent); +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/AbstractShadedShapeData.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/AbstractShadedShapeData.java new file mode 100644 index 0000000000..f1fc36950f --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/AbstractShadedShapeData.java @@ -0,0 +1,104 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.vividsolutions.jts.geom.LineString; + +/** + * Abstract class for shaded shape data. Accommodates colormapped shaded shapes + * and regular shaded shapes + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 22, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public abstract class AbstractShadedShapeData { + + public static enum DataSpace { + PIXEL, WORLD; + } + + @DynamicSerializeElement + private T info; + + @DynamicSerializeElement + private LineString[] contour; + + @DynamicSerializeElement + private DataSpace dataSpace; + + /** + * @return the info + */ + public T getInfo() { + return info; + } + + /** + * @param info + * the info to set + */ + public void setInfo(T info) { + this.info = info; + } + + /** + * @return the contour + */ + public LineString[] getContour() { + return contour; + } + + /** + * @param contour + * the contour to set + */ + public void setContour(LineString[] contour) { + this.contour = contour; + } + + /** + * @return the dataSpace + */ + public DataSpace getDataSpace() { + return dataSpace; + } + + /** + * @param dataSpace + * the dataSpace to set + */ + public void setDataSpace(DataSpace dataSpace) { + this.dataSpace = dataSpace; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/AllocatePointsEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/AllocatePointsEvent.java new file mode 100644 index 0000000000..f815e01a24 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/AllocatePointsEvent.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * TODO Add Description + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class AllocatePointsEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private int numberOfPoints; + + /** + * @return the numberOfPoints + */ + public int getNumberOfPoints() { + return numberOfPoints; + } + + /** + * @param numberOfPoints + * the numberOfPoints to set + */ + public void setNumberOfPoints(int numberOfPoints) { + this.numberOfPoints = numberOfPoints; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/ColormappedShadedShapeDataEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/ColormappedShadedShapeDataEvent.java new file mode 100644 index 0000000000..0a8acf29e3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/ColormappedShadedShapeDataEvent.java @@ -0,0 +1,168 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import java.util.LinkedList; +import java.util.List; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.AbstractShadedShapeData.DataSpace; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.LineString; + +/** + * Event for colormapped shaded shape data for display + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ColormappedShadedShapeDataEvent extends + AbstractDispatchingObjectEvent { + + @DynamicSerialize + public static class ColormappedShadedShapeData extends + AbstractShadedShapeData { + + } + + @DynamicSerialize + public static class ColormappedShadedGeometryData { + + @DynamicSerializeElement + private Geometry geometry; + + @DynamicSerializeElement + private Integer colorKey; + + /** + * @return the geometry + */ + public Geometry getGeometry() { + return geometry; + } + + /** + * @param geometry + * the geometry to set + */ + public void setGeometry(Geometry geometry) { + this.geometry = geometry; + } + + /** + * @return the colorKey + */ + public Integer getColorKey() { + return colorKey; + } + + /** + * @param colorKey + * the colorKey to set + */ + public void setColorKey(Integer colorKey) { + this.colorKey = colorKey; + } + + } + + @DynamicSerializeElement + private boolean compile = false; + + @DynamicSerializeElement + private List shapeData = new LinkedList(); + + @DynamicSerializeElement + private List geometryData = new LinkedList(); + + /** + * @return the compile + */ + public boolean isCompile() { + return compile; + } + + /** + * @param compile + * the compile to set + */ + public void setCompile(boolean compile) { + this.compile = compile; + } + + /** + * @return the shapeData + */ + public List getShapeData() { + return shapeData; + } + + /** + * @param shapeData + * the shapeData to set + */ + public void setShapeData(List shapeData) { + this.shapeData = shapeData; + } + + /** + * @return the geometryData + */ + public List getGeometryData() { + return geometryData; + } + + /** + * @param geometryData + * the geometryData to set + */ + public void setGeometryData(List geometryData) { + this.geometryData = geometryData; + } + + public void addShapeData(DataSpace dataSpace, LineString[] contours, + Integer colorKey) { + ColormappedShadedShapeData shapeDataItem = new ColormappedShadedShapeData(); + shapeDataItem.setDataSpace(dataSpace); + shapeDataItem.setInfo(colorKey); + shapeDataItem.setContour(contours); + shapeData.add(shapeDataItem); + } + + public void addGeometryData(Geometry data, Integer colorKey) { + ColormappedShadedGeometryData shapeDataItem = new ColormappedShadedGeometryData(); + shapeDataItem.setColorKey(colorKey); + shapeDataItem.setGeometry(data); + geometryData.add(shapeDataItem); + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateColormappedShadedShape.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateColormappedShadedShape.java new file mode 100644 index 0000000000..f7790e439f --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateColormappedShadedShape.java @@ -0,0 +1,85 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Event to create a new colormapped shaded shape + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 22, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateColormappedShadedShape extends + AbstractDispatchingObjectEvent implements ICreationEvent { + + @DynamicSerializeElement + private GeneralGridGeometry targetGeometry; + + @DynamicSerializeElement + private boolean tesselate; + + /** + * @return the targetGeometry + */ + public GeneralGridGeometry getTargetGeometry() { + return targetGeometry; + } + + /** + * @param targetGeometry + * the targetGeometry to set + */ + public void setTargetGeometry(GeneralGridGeometry targetGeometry) { + this.targetGeometry = targetGeometry; + } + + /** + * @return the tesselate + */ + public boolean isTesselate() { + return tesselate; + } + + /** + * @param tesselate + * the tesselate to set + */ + public void setTesselate(boolean tesselate) { + this.tesselate = tesselate; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateShadedShapeEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateShadedShapeEvent.java new file mode 100644 index 0000000000..ab44fa6beb --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateShadedShapeEvent.java @@ -0,0 +1,103 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Event for creating a shaded shape + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateShadedShapeEvent extends AbstractDispatchingObjectEvent + implements ICreationEvent { + + @DynamicSerializeElement + private GeneralGridGeometry targetGeometry; + + @DynamicSerializeElement + private boolean mutable; + + @DynamicSerializeElement + private boolean tesselate; + + /** + * @return the targetGeometry + */ + public GeneralGridGeometry getTargetGeometry() { + return targetGeometry; + } + + /** + * @param targetGeometry + * the targetGeometry to set + */ + public void setTargetGeometry(GeneralGridGeometry targetGeometry) { + this.targetGeometry = targetGeometry; + } + + /** + * @return the mutable + */ + public boolean isMutable() { + return mutable; + } + + /** + * @param mutable + * the mutable to set + */ + public void setMutable(boolean mutable) { + this.mutable = mutable; + } + + /** + * @return the tesselate + */ + public boolean isTesselate() { + return tesselate; + } + + /** + * @param tesselate + * the tesselate to set + */ + public void setTesselate(boolean tesselate) { + this.tesselate = tesselate; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateWireframeShapeEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateWireframeShapeEvent.java new file mode 100644 index 0000000000..13463b2fdb --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/CreateWireframeShapeEvent.java @@ -0,0 +1,151 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import org.geotools.coverage.grid.GeneralGridGeometry; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IExtent; +import com.raytheon.uf.viz.core.PixelExtent; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.ICreationEvent; + +/** + * Event to create a new wireframe shape object + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 27, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class CreateWireframeShapeEvent extends AbstractDispatchingObjectEvent + implements ICreationEvent { + + @DynamicSerializeElement + private GeneralGridGeometry gridGeometry; + + @DynamicSerializeElement + private boolean mutable; + + @DynamicSerializeElement + private Float simplificationLevel; + + @DynamicSerializeElement + private Boolean spatialChopFlag; + + @DynamicSerializeElement + private double[] extent; + + /** + * @return the gridGeometry + */ + public GeneralGridGeometry getGridGeometry() { + return gridGeometry; + } + + /** + * @param gridGeometry + * the gridGeometry to set + */ + public void setGridGeometry(GeneralGridGeometry gridGeometry) { + this.gridGeometry = gridGeometry; + } + + /** + * @return the mutable + */ + public boolean isMutable() { + return mutable; + } + + /** + * @param mutable + * the mutable to set + */ + public void setMutable(boolean mutable) { + this.mutable = mutable; + } + + /** + * @return the simplificationLevel + */ + public Float getSimplificationLevel() { + return simplificationLevel; + } + + /** + * @param simplificationLevel + * the simplificationLevel to set + */ + public void setSimplificationLevel(Float simplificationLevel) { + this.simplificationLevel = simplificationLevel; + } + + /** + * @return the spatialChopFlag + */ + public Boolean isSpatialChopFlag() { + return spatialChopFlag; + } + + /** + * @param spatialChopFlag + * the spatialChopFlag to set + */ + public void setSpatialChopFlag(Boolean spatialChopFlag) { + this.spatialChopFlag = spatialChopFlag; + } + + /** + * @return the extent + */ + public double[] getExtent() { + return extent; + } + + /** + * @param extent + * the extent to set + */ + public void setExtent(double[] extent) { + this.extent = extent; + } + + public void setIExtent(IExtent extent) { + if (extent != null) { + setExtent(new double[] { extent.getMinX(), extent.getMaxX(), + extent.getMinY(), extent.getMaxY() }); + } + } + + public IExtent getIExtent() { + return new PixelExtent(extent[0], extent[1], extent[2], extent[3]); + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/DrawShadedShapeEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/DrawShadedShapeEvent.java new file mode 100644 index 0000000000..3430379685 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/DrawShadedShapeEvent.java @@ -0,0 +1,82 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for drawing a single shaded shape + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawShadedShapeEvent extends AbstractDispatchingObjectEvent + implements IRenderEvent { + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * createDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public DrawShadedShapeEvent createDiffObject(IRenderEvent event) { + return (DrawShadedShapeEvent) event; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + setObjectId(((DrawShadedShapeEvent) diffEvent).getObjectId()); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + @Override + public Object clone() { + DrawShadedShapeEvent newInstance = new DrawShadedShapeEvent(); + newInstance.applyDiffObject(this); + newInstance.setDisplayId(getDisplayId()); + return newInstance; + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/DrawShadedShapesEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/DrawShadedShapesEvent.java new file mode 100644 index 0000000000..19e25b49ed --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/DrawShadedShapesEvent.java @@ -0,0 +1,164 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.rendering.AbstractRemoteGraphicsBulkRenderEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for drawing a group of shaded shapes + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class DrawShadedShapesEvent extends + AbstractRemoteGraphicsBulkRenderEvent { + + @DynamicSerializeElement + private float alpha; + + @DynamicSerializeElement + private float brightness; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent + * #createDiffObject(com.raytheon.uf.viz + * .remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public DrawShadedShapesEvent createDiffObject(IRenderEvent event) { + DrawShadedShapesEvent diffEvent = (DrawShadedShapesEvent) event; + DrawShadedShapesEvent diffObject = (DrawShadedShapesEvent) super + .createDiffObject(diffEvent); + diffObject.alpha = diffEvent.alpha; + diffObject.brightness = diffEvent.brightness; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent + * #applyDiffObject(com.raytheon.uf.viz. + * remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + super.applyDiffObject(diffEvent); + DrawShadedShapesEvent diffObject = (DrawShadedShapesEvent) diffEvent; + this.alpha = diffObject.alpha; + this.brightness = diffObject.brightness; + } + + /** + * @return the alpha + */ + public float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(float alpha) { + this.alpha = alpha; + } + + /** + * @return the brightness + */ + public float getBrightness() { + return brightness; + } + + /** + * @param brightness + * the brightness to set + */ + public void setBrightness(float brightness) { + this.brightness = brightness; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent#getObjectClass() + */ + @Override + protected Class getObjectClass() { + return DrawShadedShapeEvent.class; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + DrawShadedShapesEvent other = (DrawShadedShapesEvent) obj; + if (Float.floatToIntBits(alpha) != Float.floatToIntBits(other.alpha)) + return false; + if (Float.floatToIntBits(brightness) != Float + .floatToIntBits(other.brightness)) + return false; + return true; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsBulkRenderEvent#clone() + */ + @Override + public Object clone() { + DrawShadedShapesEvent event = (DrawShadedShapesEvent) super.clone(); + event.alpha = alpha; + event.brightness = brightness; + return event; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/RenderColormappedShadedShape.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/RenderColormappedShadedShape.java new file mode 100644 index 0000000000..69d5c4091b --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/RenderColormappedShadedShape.java @@ -0,0 +1,191 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import java.util.Map; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event for rendering a colormapped shaded shape + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 22, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class RenderColormappedShadedShape extends + AbstractDispatchingObjectEvent implements IRenderEvent { + + @DynamicSerializeElement + private Map colorMap; + + @DynamicSerializeElement + private Float alpha; + + @DynamicSerializeElement + private Float brightness; + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering. + * AbstractRemoteGraphicsRenderEvent + * #createDiffObject(com.raytheon.uf.viz.remote + * .graphics.events.rendering.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + RenderColormappedShadedShape e = (RenderColormappedShadedShape) event; + RenderColormappedShadedShape diffObject = new RenderColormappedShadedShape(); + diffObject.setObjectId(e.getObjectId()); + if (alpha.equals(e.alpha) == false) + diffObject.alpha = e.alpha; + if (brightness.equals(e.brightness) == false) + diffObject.brightness = e.brightness; + if (colorMap.equals(e.colorMap) == false) + diffObject.colorMap = e.colorMap; + return diffObject; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent# + * applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + RenderColormappedShadedShape diffObject = (RenderColormappedShadedShape) diffEvent; + setObjectId(diffObject.getObjectId()); + if (diffObject.alpha != null) + alpha = diffObject.alpha; + if (diffObject.brightness != null) + brightness = diffObject.brightness; + if (diffObject.colorMap != null) + colorMap = diffObject.colorMap; + } + + /** + * @return the colorMap + */ + public Map getColorMap() { + return colorMap; + } + + /** + * @param colorMap + * the colorMap to set + */ + public void setColorMap(Map colorMap) { + this.colorMap = colorMap; + } + + /** + * @return the alpha + */ + public Float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(Float alpha) { + this.alpha = alpha; + } + + /** + * @return the brightness + */ + public Float getBrightness() { + return brightness; + } + + /** + * @param brightness + * the brightness to set + */ + public void setBrightness(Float brightness) { + this.brightness = brightness; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + @Override + public Object clone() { + RenderColormappedShadedShape newInstance = new RenderColormappedShadedShape(); + newInstance.applyDiffObject(this); + newInstance.setDisplayId(getDisplayId()); + return newInstance; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + RenderColormappedShadedShape other = (RenderColormappedShadedShape) obj; + if (alpha == null) { + if (other.alpha != null) + return false; + } else if (!alpha.equals(other.alpha)) + return false; + if (brightness == null) { + if (other.brightness != null) + return false; + } else if (!brightness.equals(other.brightness)) + return false; + if (colorMap == null) { + if (other.colorMap != null) + return false; + } else if (!colorMap.equals(other.colorMap)) + return false; + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/RenderWireframeShapeEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/RenderWireframeShapeEvent.java new file mode 100644 index 0000000000..a6f83ef747 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/RenderWireframeShapeEvent.java @@ -0,0 +1,220 @@ +/** + * This software was developed and / or modified by Raytheon Company; + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street; Suite 340 + * Mail Stop B8 + * Omaha; NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.core.IGraphicsTarget.LineStyle; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.rendering.IRenderEvent; + +/** + * Event type for rendering a wireframe shape + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Apr 9; 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class RenderWireframeShapeEvent extends AbstractDispatchingObjectEvent + implements IRenderEvent { + + @DynamicSerializeElement + private RGB color; + + @DynamicSerializeElement + private float lineWidth; + + @DynamicSerializeElement + private LineStyle lineStyle; + + @DynamicSerializeElement + private Integer fontId; + + @DynamicSerializeElement + private Float alpha; + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#createDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public IRenderEvent createDiffObject(IRenderEvent event) { + return event; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.remote.graphics.events.IRenderEvent#applyDiffObject + * (com.raytheon.uf.viz.remote.graphics.events.IRenderEvent) + */ + @Override + public void applyDiffObject(IRenderEvent diffEvent) { + RenderWireframeShapeEvent event = (RenderWireframeShapeEvent) diffEvent; + this.setObjectId(event.getObjectId()); + this.alpha = event.alpha; + this.color = event.color; + this.fontId = event.fontId; + this.lineStyle = event.lineStyle; + this.lineWidth = event.lineWidth; + } + + /** + * @return the lineWidth + */ + public float getLineWidth() { + return lineWidth; + } + + /** + * @param lineWidth + * the lineWidth to set + */ + public void setLineWidth(float lineWidth) { + this.lineWidth = lineWidth; + } + + /** + * @return the lineStyle + */ + public LineStyle getLineStyle() { + return lineStyle; + } + + /** + * @param lineStyle + * the lineStyle to set + */ + public void setLineStyle(LineStyle lineStyle) { + this.lineStyle = lineStyle; + } + + /** + * @return the fontId + */ + public Integer getFontId() { + return fontId; + } + + /** + * @param fontId + * the fontId to set + */ + public void setFontId(Integer fontId) { + this.fontId = fontId; + } + + /** + * @return the alpha + */ + public Float getAlpha() { + return alpha; + } + + /** + * @param alpha + * the alpha to set + */ + public void setAlpha(Float alpha) { + this.alpha = alpha; + } + + /** + * @return the color + */ + public RGB getColor() { + return color; + } + + /** + * @param color + * the color to set + */ + public void setColor(RGB color) { + this.color = color; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + RenderWireframeShapeEvent other = (RenderWireframeShapeEvent) obj; + if (alpha == null) { + if (other.alpha != null) + return false; + } else if (!alpha.equals(other.alpha)) + return false; + if (color == null) { + if (other.color != null) + return false; + } else if (!color.equals(other.color)) + return false; + if (fontId == null) { + if (other.fontId != null) + return false; + } else if (!fontId.equals(other.fontId)) + return false; + if (lineStyle != other.lineStyle) + return false; + if (Float.floatToIntBits(lineWidth) != Float + .floatToIntBits(other.lineWidth)) + return false; + return true; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#clone() + */ + @Override + public Object clone() { + RenderWireframeShapeEvent newInstance = new RenderWireframeShapeEvent(); + newInstance.applyDiffObject(this); + newInstance.setDisplayId(getDisplayId()); + return newInstance; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/SetShadedShapeFillPattern.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/SetShadedShapeFillPattern.java new file mode 100644 index 0000000000..d53c1021c3 --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/SetShadedShapeFillPattern.java @@ -0,0 +1,63 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; + +/** + * Event for setting the fill pattern on a shaded shape + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class SetShadedShapeFillPattern extends AbstractDispatchingObjectEvent { + + @DynamicSerializeElement + private byte[] fillPattern; + + /** + * @return the fillPattern + */ + public byte[] getFillPattern() { + return fillPattern; + } + + /** + * @param fillPattern + * the fillPattern to set + */ + public void setFillPattern(byte[] fillPattern) { + this.fillPattern = fillPattern; + } + +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/ShadedShapeDataEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/ShadedShapeDataEvent.java new file mode 100644 index 0000000000..a34496813a --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/ShadedShapeDataEvent.java @@ -0,0 +1,100 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.swt.graphics.RGB; + +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.AbstractShadedShapeData.DataSpace; +import com.vividsolutions.jts.geom.LineString; + +/** + * Event for shaded shape data for display + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +public class ShadedShapeDataEvent extends AbstractDispatchingObjectEvent { + + @DynamicSerialize + public static class ShadedShapeData extends AbstractShadedShapeData { + + } + + @DynamicSerializeElement + private List shapeData = new LinkedList(); + + @DynamicSerializeElement + private boolean compile = false; + + /** + * @return the shapeData + */ + public List getShapeData() { + return shapeData; + } + + /** + * @param shapeData + * the shapeData to set + */ + public void setShapeData(List shapeData) { + this.shapeData = shapeData; + } + + /** + * @return the compile + */ + public boolean isCompile() { + return compile; + } + + /** + * @param compile + * the compile to set + */ + public void setCompile(boolean compile) { + this.compile = compile; + } + + public void addShapeData(DataSpace dataSpace, LineString[] data, RGB color) { + ShadedShapeData shapeDataItem = new ShadedShapeData(); + shapeDataItem.setDataSpace(dataSpace); + shapeDataItem.setContour(data); + shapeDataItem.setInfo(color); + shapeData.add(shapeDataItem); + } +} diff --git a/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/WireframeShapeDataEvent.java b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/WireframeShapeDataEvent.java new file mode 100644 index 0000000000..66564b4b4c --- /dev/null +++ b/cave/com.raytheon.uf.viz.remote.graphics/src/com/raytheon/uf/viz/remote/graphics/events/shapes/WireframeShapeDataEvent.java @@ -0,0 +1,274 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.remote.graphics.events.shapes; + +import java.util.LinkedList; +import java.util.List; + +import com.raytheon.uf.common.serialization.IDeserializationContext; +import com.raytheon.uf.common.serialization.ISerializationContext; +import com.raytheon.uf.common.serialization.ISerializationTypeAdapter; +import com.raytheon.uf.common.serialization.SerializationException; +import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; +import com.raytheon.uf.common.serialization.annotations.DynamicSerializeTypeAdapter; +import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent; +import com.raytheon.uf.viz.remote.graphics.events.shapes.WireframeShapeDataEvent.WireframeShapeDataAdapter; +import com.vividsolutions.jts.geom.Coordinate; + +/** + * Wireframe shape data event which contains coordinates and labels to add to + * the wireframe shape referenced by this event + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Mar 26, 2012            mschenke     Initial creation
+ * 
+ * 
+ * + * @author mschenke + * @version 1.0 + */ +@DynamicSerialize +@DynamicSerializeTypeAdapter(factory = WireframeShapeDataAdapter.class) +public class WireframeShapeDataEvent extends AbstractDispatchingObjectEvent { + + public static class WireframeShapeDataAdapter implements + ISerializationTypeAdapter { + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.common.serialization.ISerializationTypeAdapter#serialize + * (com.raytheon.uf.common.serialization.ISerializationContext, + * java.lang.Object) + */ + @Override + public void serialize(ISerializationContext serializer, + WireframeShapeDataEvent object) throws SerializationException { + serializer.writeI32(object.getDisplayId()); + serializer.writeI32(object.getObjectId()); + serializer.writeI32(object.labels.size()); + for (Label l : object.labels) { + serializer.writeString(l.getText()); + serializer.writeDoubleArray(l.getPoint()); + } + serializer.writeI32(object.pixelCoordinates.size()); + for (double[][] coords : object.pixelCoordinates) { + serializer.writeI32(coords.length); + for (double[] coord : coords) { + serializer.writeDoubleArray(coord); + } + } + serializer.writeI32(object.worldCoordiantes.size()); + for (Coordinate[] coordArray : object.worldCoordiantes) { + double[] packedCoords = new double[coordArray.length * 3]; + int i = 0; + for (Coordinate coord : coordArray) { + packedCoords[i++] = coord.x; + packedCoords[i++] = coord.y; + packedCoords[i++] = coord.z; + } + serializer.writeDoubleArray(packedCoords); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.common.serialization.ISerializationTypeAdapter# + * deserialize + * (com.raytheon.uf.common.serialization.IDeserializationContext) + */ + @Override + public WireframeShapeDataEvent deserialize( + IDeserializationContext deserializer) + throws SerializationException { + WireframeShapeDataEvent data = new WireframeShapeDataEvent(); + data.setDisplayId(deserializer.readI32()); + data.setObjectId(deserializer.readI32()); + int size = deserializer.readI32(); + for (int i = 0; i < size; ++i) { + data.addLabel(deserializer.readString(), + deserializer.readDoubleArray()); + } + + size = deserializer.readI32(); + for (int i = 0; i < size; ++i) { + int size2 = deserializer.readI32(); + double[][] coords = new double[size2][]; + for (int j = 0; j < size2; ++j) { + coords[j] = deserializer.readDoubleArray(); + } + data.addPixelCoordinates(coords); + } + + size = deserializer.readI32(); + for (int i = 0; i < size; ++i) { + double[] packedCoords = deserializer.readDoubleArray(); + Coordinate[] worldCoords = new Coordinate[packedCoords.length / 3]; + for (int j = 0, k = 0; j < worldCoords.length; j++) { + worldCoords[j] = new Coordinate(packedCoords[k++], + packedCoords[k++], packedCoords[k++]); + } + data.addWorldCoordinates(worldCoords); + } + + return data; + } + } + + @DynamicSerialize + public static class Label { + + @DynamicSerializeElement + private String text; + + @DynamicSerializeElement + private double[] point; + + private Label(String text, double[] point) { + this.text = text; + this.point = point; + } + + public Label() { + + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text + * the text to set + */ + public void setText(String text) { + this.text = text; + } + + /** + * @return the point + */ + public double[] getPoint() { + return point; + } + + /** + * @param point + * the point to set + */ + public void setPoint(double[] point) { + this.point = point; + } + } + + @DynamicSerializeElement + private List pixelCoordinates = new LinkedList(); + + @DynamicSerializeElement + private List worldCoordiantes = new LinkedList(); + + @DynamicSerializeElement + private List