Merge branch 'master_14.3.1-4' into asm_14.3.1
Conflicts: cave/com.raytheon.uf.viz.monitor.ffmp/src/com/raytheon/uf/viz/monitor/ffmp/ui/rsc/FFMPResource.java edexOsgi/com.raytheon.uf.edex.grid.staticdata/src/com/raytheon/uf/edex/grid/staticdata/StaticDataGenerator.java edexOsgi/com.raytheon.uf.edex.plugin.grid/utility/common_static/base/purge/gridPurgeRules.xml Former-commit-id: 52358cb3e2ba2c7ff4ff9c9a5de03af50c3a1199
This commit is contained in:
commit
011d121e4b
1313 changed files with 24160 additions and 40597 deletions
Binary file not shown.
|
@ -70,34 +70,6 @@
|
|||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.ecf"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.ecf.filetransfer"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.ecf.provider.filetransfer"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.ecf.identity"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.eclipse.equinox.p2.touchpoint.eclipse"
|
||||
download-size="0"
|
||||
|
@ -237,11 +209,4 @@
|
|||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
<plugin
|
||||
id="org.hamcrest.core"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
|
||||
</feature>
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
id="org.apache.commons.compress"
|
||||
download-size="0"
|
||||
install-size="0"
|
||||
version="0.0.0"
|
||||
unpack="false"/>
|
||||
version="0.0.0"/>
|
||||
|
||||
</feature>
|
||||
|
|
|
@ -30,6 +30,14 @@
|
|||
recursive="false"
|
||||
extensionFilter=".xml">
|
||||
</path>
|
||||
<path
|
||||
application="Archive"
|
||||
localizationType="COMMON_STATIC"
|
||||
name="gui"
|
||||
value="archiver/gui"
|
||||
recursive="false"
|
||||
extensionFilter=".xml">
|
||||
</path>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.menus">
|
||||
|
|
|
@ -17,25 +17,28 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.edex.uengine;
|
||||
|
||||
package com.raytheon.uf.viz.archive.data;
|
||||
|
||||
/**
|
||||
* Activator for uEngine component
|
||||
* A listener to notify when SizeJob has obtain all display data.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 8, 2008 njensen Initial creation
|
||||
* Apr 23, 2014 3045 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author njensen
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class Activator {
|
||||
|
||||
public static final String PLUGIN_ID = "com.raytheon.edex.uengine";
|
||||
|
||||
public interface ILoadDisplayDataListener {
|
||||
/**
|
||||
* Called by SizeJob after obtaining all display data for all
|
||||
* archive/category tables.
|
||||
*/
|
||||
public void loadedAllDisplayData();
|
||||
}
|
|
@ -52,6 +52,7 @@ import com.raytheon.uf.common.time.util.TimeUtil;
|
|||
* Dec 11, 2013 #2603 rferrel Selected list changed to a Set.
|
||||
* Dec 11, 2013 #2624 rferrel Clear display variables when recomputing sizes.
|
||||
* Mar 27, 2014 #2879 rferrel Loading Case no longer changes Start/End times.
|
||||
* Apr 23, 2014 #3045 rferrel Changes to prevent race condition while getting labels.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -156,17 +157,17 @@ public class SizeJob extends Job {
|
|||
private boolean stopComputeSize;
|
||||
|
||||
/**
|
||||
* Priority queue for getting display data for an archive/category.
|
||||
* Priority queue for getting display data all archive/category tables.
|
||||
*/
|
||||
// Do not use a PriorityBlockingQueue since the load select and change
|
||||
// display methods need to be notified when the display data is available.
|
||||
private final PriorityQueue<MissingData> missingDataQueue = new PriorityQueue<SizeJob.MissingData>(
|
||||
DEFAULT_INITIAL_CAPACITY, new Comparator<MissingData>() {
|
||||
private final PriorityQueue<LoadDisplayData> loadDisplayDataQueue = new PriorityQueue<SizeJob.LoadDisplayData>(
|
||||
DEFAULT_INITIAL_CAPACITY, new Comparator<LoadDisplayData>() {
|
||||
|
||||
@Override
|
||||
public int compare(MissingData o1, MissingData o2) {
|
||||
if (o1.visiable != o2.visiable) {
|
||||
return o1.visiable ? -1 : +1;
|
||||
public int compare(LoadDisplayData o1, LoadDisplayData o2) {
|
||||
if (o1.visible != o2.visible) {
|
||||
return o1.visible ? -1 : +1;
|
||||
}
|
||||
if (o1.isSelected() != o2.isSelected()) {
|
||||
return o1.isSelected() ? -1 : +1;
|
||||
|
@ -182,16 +183,22 @@ public class SizeJob extends Job {
|
|||
});
|
||||
|
||||
/**
|
||||
* Job for processing the missing data queue.
|
||||
* Job for obtaining display data for all the archive/category tables.
|
||||
*/
|
||||
private final MissingDataJob missingDataJob = new MissingDataJob();
|
||||
private LoadDisplayDataJob loadDisplayDataJob;
|
||||
|
||||
/**
|
||||
* Listener to invoke when all display data loaded.
|
||||
*/
|
||||
private final ILoadDisplayDataListener loadDisplayDataListener;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public SizeJob() {
|
||||
public SizeJob(ILoadDisplayDataListener loadDisplayDataListener) {
|
||||
super("Size Job");
|
||||
setSystem(true);
|
||||
this.loadDisplayDataListener = loadDisplayDataListener;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,9 +292,11 @@ public class SizeJob extends Job {
|
|||
* Check all displayData selection state so only the data in selections are
|
||||
* set.
|
||||
*
|
||||
* @param selections
|
||||
* @param selectName
|
||||
* @param type
|
||||
* @return errorMessage when unable to load else null
|
||||
*/
|
||||
public void loadSelect(String selectName, ArchiveConstants.Type type) {
|
||||
public String loadSelect(String selectName, ArchiveConstants.Type type) {
|
||||
ArchiveConfigManager manager = ArchiveConfigManager.getInstance();
|
||||
String fileName = ArchiveConstants.selectFileName(type, selectName);
|
||||
SelectConfig selections = manager.loadSelection(fileName);
|
||||
|
@ -301,24 +310,18 @@ public class SizeJob extends Job {
|
|||
for (String categoryName : archiveInfo.getCategoryNames()) {
|
||||
Set<String> selectionsSet = selections.getSelectedSet(
|
||||
archiveName, categoryName);
|
||||
MissingData missingData = removeMissingData(archiveName,
|
||||
categoryName);
|
||||
if (missingData != null) {
|
||||
missingData.setSelectedSet(selectionsSet);
|
||||
addMissingData(missingData);
|
||||
} else {
|
||||
CategoryInfo categoryInfo = archiveInfo.get(categoryName);
|
||||
for (DisplayData displayData : categoryInfo
|
||||
.getDisplayDataList()) {
|
||||
String displayLabel = displayData.getDisplayLabel();
|
||||
boolean selected = selectionsSet.contains(displayLabel);
|
||||
if (selected != displayData.isSelected()) {
|
||||
setSelect(displayData, selected);
|
||||
}
|
||||
CategoryInfo categoryInfo = archiveInfo.get(categoryName);
|
||||
for (DisplayData displayData : categoryInfo
|
||||
.getDisplayDataList()) {
|
||||
String displayLabel = displayData.getDisplayLabel();
|
||||
boolean selected = selectionsSet.contains(displayLabel);
|
||||
if (selected != displayData.isSelected()) {
|
||||
setSelect(displayData, selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,10 +330,13 @@ public class SizeJob extends Job {
|
|||
* @return selected
|
||||
*/
|
||||
public List<DisplayData> getSelectAll() {
|
||||
synchronized (missingDataQueue) {
|
||||
while (!missingDataQueue.isEmpty()) {
|
||||
if (missingDataJob.currentMissingData == null
|
||||
|| missingDataJob.currentMissingData.isSelected()) {
|
||||
synchronized (loadDisplayDataQueue) {
|
||||
while (!loadDisplayDataQueue.isEmpty()) {
|
||||
if ((loadDisplayDataJob.currentLoadDisplayData == null)
|
||||
|| loadDisplayDataJob.currentLoadDisplayData
|
||||
.isVisible()
|
||||
|| loadDisplayDataJob.currentLoadDisplayData
|
||||
.isSelected()) {
|
||||
missingDataQueueWait();
|
||||
} else {
|
||||
break;
|
||||
|
@ -440,33 +446,81 @@ public class SizeJob extends Job {
|
|||
}
|
||||
|
||||
/**
|
||||
* Change the archive/category display.
|
||||
*
|
||||
* @param archiveName
|
||||
* - non null value
|
||||
* @param categoryName
|
||||
* @return displayData when display needs to change otherwise null
|
||||
* - non null value
|
||||
* @return true if archiveName and categoryName match the current display
|
||||
*/
|
||||
public boolean isCurrentDisplay(String archiveName, String categoryName) {
|
||||
return archiveName.equals(displayArchive)
|
||||
&& categoryName.equals(displayCategory);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a display data list to replace the contents of the
|
||||
* GUI's achive/category display table or a null list if no update is
|
||||
* needed. It is assumed this method is called from an non-UI thread.
|
||||
*
|
||||
* @param archiveName
|
||||
* - archive for the new display table
|
||||
* @param categoryName
|
||||
* - category for the new display table
|
||||
* @param shutdown
|
||||
* - Becomes true when user requests a different table while this
|
||||
* is waiting for data.
|
||||
* @return displayData
|
||||
*/
|
||||
public List<DisplayData> changeDisplay(String archiveName,
|
||||
String categoryName) {
|
||||
String categoryName, AtomicBoolean shutdown) {
|
||||
List<DisplayData> displayDatas = null;
|
||||
|
||||
// Only get data when the display really needs to be changed.
|
||||
if (!archiveName.equals(displayArchive)
|
||||
|| !categoryName.equals(displayCategory)) {
|
||||
MissingData missingData = removeMissingData(archiveName,
|
||||
|
||||
// Update visible status of current display.
|
||||
if ((displayArchive != null) && (displayCategory != null)) {
|
||||
LoadDisplayData currentMissingData = removeLoadDisplayData(
|
||||
displayArchive, displayCategory);
|
||||
if (currentMissingData != null) {
|
||||
currentMissingData.setVisible(false);
|
||||
addLoadDisplayData(currentMissingData);
|
||||
}
|
||||
}
|
||||
|
||||
LoadDisplayData missingData = removeLoadDisplayData(archiveName,
|
||||
categoryName);
|
||||
displayArchive = archiveName;
|
||||
displayCategory = categoryName;
|
||||
|
||||
// Update visible status of the new current display.
|
||||
if (missingData != null) {
|
||||
missingData.setVisiable(true);
|
||||
synchronized (missingDataQueue) {
|
||||
addMissingData(missingData);
|
||||
while (missingDataQueue.contains(missingData)) {
|
||||
missingDataQueueWait();
|
||||
synchronized (loadDisplayDataQueue) {
|
||||
missingData.setVisible(true);
|
||||
addLoadDisplayData(missingData);
|
||||
|
||||
/*
|
||||
* Wait for the display data to be loaded or no longer
|
||||
* needed.
|
||||
*/
|
||||
while (loadDisplayDataJob.processing(missingData)
|
||||
&& !shutdown.get()) {
|
||||
missingDataQueueWait(500L);
|
||||
}
|
||||
}
|
||||
}
|
||||
displayDatas = archiveInfoMap.get(archiveName).get(categoryName)
|
||||
.getDisplayDataList();
|
||||
displayArchive = archiveName;
|
||||
displayCategory = categoryName;
|
||||
changeDisplay(displayDatas);
|
||||
|
||||
/*
|
||||
* If user still needs the data update status of old visible data
|
||||
* and the new visible data.
|
||||
*/
|
||||
if (!shutdown.get()) {
|
||||
displayDatas = archiveInfoMap.get(archiveName)
|
||||
.get(categoryName).getDisplayDataList();
|
||||
changeDisplay(displayDatas);
|
||||
}
|
||||
}
|
||||
return displayDatas;
|
||||
}
|
||||
|
@ -474,7 +528,7 @@ public class SizeJob extends Job {
|
|||
/**
|
||||
* Change to display all selected data..
|
||||
*
|
||||
* @return displayhData when display needs to change otherwise null.
|
||||
* @return displayData when display needs to change otherwise null.
|
||||
*/
|
||||
public List<DisplayData> changeDisplayAll() {
|
||||
List<DisplayData> selectedData = null;
|
||||
|
@ -499,7 +553,7 @@ public class SizeJob extends Job {
|
|||
}
|
||||
iRetentionHour.setRetentionTimes(selections.getStarRetentionHours());
|
||||
|
||||
missingDataQueue.clear();
|
||||
loadDisplayDataQueue.clear();
|
||||
|
||||
visibleList = manager.getDisplayData(displayArchive, displayCategory,
|
||||
false);
|
||||
|
@ -527,51 +581,48 @@ public class SizeJob extends Job {
|
|||
} else {
|
||||
selectedSet = selections.getSelectedSet(archiveName,
|
||||
categoryName);
|
||||
MissingData missingData = new MissingData(archiveName,
|
||||
categoryName, selectedSet);
|
||||
missingDataQueue.add(missingData);
|
||||
LoadDisplayData missingData = new LoadDisplayData(
|
||||
archiveName, categoryName, selectedSet);
|
||||
loadDisplayDataQueue.add(missingData);
|
||||
}
|
||||
}
|
||||
put(archiveName, archiveInfo);
|
||||
}
|
||||
|
||||
missingDataJob.schedule();
|
||||
loadDisplayDataJob = new LoadDisplayDataJob(loadDisplayDataListener,
|
||||
loadDisplayDataQueue.size());
|
||||
|
||||
loadDisplayDataJob.schedule();
|
||||
|
||||
return selections.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find and remove the missing data from the missing data queue.
|
||||
* Find and remove the associated load display data from the queue.
|
||||
*
|
||||
* @param archiveName
|
||||
* @param categoryName
|
||||
* @return missingData or null if not on the missing data queue
|
||||
* @return loadDisplayData or null if no longer on the queue
|
||||
*/
|
||||
private MissingData removeMissingData(String archiveName,
|
||||
private LoadDisplayData removeLoadDisplayData(String archiveName,
|
||||
String categoryName) {
|
||||
MissingData missingData = null;
|
||||
synchronized (missingDataQueue) {
|
||||
if (missingDataJob.currentMissingData != null
|
||||
&& archiveName
|
||||
.equals(missingDataJob.currentMissingData.archive)
|
||||
&& categoryName
|
||||
.equals(missingDataJob.currentMissingData.category)) {
|
||||
// Finish the process of getting the data.
|
||||
missingDataQueueWait();
|
||||
} else if (!missingDataQueue.isEmpty()) {
|
||||
Iterator<MissingData> iterator = missingDataQueue.iterator();
|
||||
LoadDisplayData loadDisplayData = null;
|
||||
synchronized (loadDisplayDataQueue) {
|
||||
if (!loadDisplayDataQueue.isEmpty()) {
|
||||
Iterator<LoadDisplayData> iterator = loadDisplayDataQueue
|
||||
.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
MissingData md = iterator.next();
|
||||
LoadDisplayData md = iterator.next();
|
||||
if (md.archive.equals(archiveName)
|
||||
&& md.category.equals(categoryName)) {
|
||||
iterator.remove();
|
||||
missingData = md;
|
||||
loadDisplayData = md;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return missingData;
|
||||
return loadDisplayData;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -580,9 +631,20 @@ public class SizeJob extends Job {
|
|||
* @return false when interrupted exception
|
||||
*/
|
||||
private boolean missingDataQueueWait() {
|
||||
return missingDataQueueWait(0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for notification that the current missing data is finished
|
||||
* processing or the desired time has lapsed.
|
||||
*
|
||||
* @param time
|
||||
* @return false when interrupted exception
|
||||
*/
|
||||
private boolean missingDataQueueWait(long time) {
|
||||
boolean state = true;
|
||||
try {
|
||||
missingDataQueue.wait();
|
||||
loadDisplayDataQueue.wait(time);
|
||||
} catch (InterruptedException e) {
|
||||
state = false;
|
||||
statusHandler.handle(Priority.INFO, e.getLocalizedMessage(), e);
|
||||
|
@ -591,32 +653,30 @@ public class SizeJob extends Job {
|
|||
}
|
||||
|
||||
/**
|
||||
* This inserts a load display data onto the queue. Should
|
||||
*
|
||||
* @param missingData
|
||||
* @param loadDisplayData
|
||||
*/
|
||||
private void addMissingData(MissingData missingData) {
|
||||
synchronized (missingDataQueue) {
|
||||
missingDataQueue.add(missingData);
|
||||
if (missingDataJob.getState() == Job.NONE) {
|
||||
missingDataJob.schedule();
|
||||
private void addLoadDisplayData(LoadDisplayData loadDisplayData) {
|
||||
synchronized (loadDisplayDataQueue) {
|
||||
loadDisplayDataQueue.add(loadDisplayData);
|
||||
if (loadDisplayDataJob.getState() == Job.NONE) {
|
||||
loadDisplayDataJob.schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change update visible to the new list.
|
||||
* Change visible status to reflect the new list.
|
||||
*
|
||||
* @param newDisplays
|
||||
*/
|
||||
private void changeDisplay(List<DisplayData> newDisplays) {
|
||||
List<DisplayData> oldDisplays = visibleList;
|
||||
visibleList = newDisplays;
|
||||
List<DisplayData> visibleList = new ArrayList<DisplayData>(newDisplays);
|
||||
|
||||
for (DisplayData displayData : oldDisplays) {
|
||||
if (!visibleList.remove(displayData)) {
|
||||
setVisible(displayData, false);
|
||||
}
|
||||
setVisible(displayData, false);
|
||||
}
|
||||
|
||||
for (DisplayData displayData : visibleList) {
|
||||
|
@ -761,25 +821,25 @@ public class SizeJob extends Job {
|
|||
@Override
|
||||
protected void canceling() {
|
||||
clearQueue();
|
||||
missingDataQueue.clear();
|
||||
missingDataJob.cancel();
|
||||
loadDisplayDataQueue.clear();
|
||||
loadDisplayDataJob.cancel();
|
||||
shutdown.set(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Class used by the missing data job to obtain display data for given
|
||||
* archive/category off the UI thread.
|
||||
* Class used to track missing display data for the archive/category tables.
|
||||
* Allowing the information to be retrieved in a non-UI thread.
|
||||
*/
|
||||
private static class MissingData {
|
||||
private static class LoadDisplayData {
|
||||
protected final String archive;
|
||||
|
||||
protected final String category;
|
||||
|
||||
protected final Set<String> selectedSet;
|
||||
|
||||
protected boolean visiable = false;
|
||||
protected boolean visible = false;
|
||||
|
||||
public MissingData(String archive, String category,
|
||||
public LoadDisplayData(String archive, String category,
|
||||
Set<String> selectedSet) {
|
||||
this.archive = archive;
|
||||
this.category = category;
|
||||
|
@ -790,21 +850,20 @@ public class SizeJob extends Job {
|
|||
return !selectedSet.isEmpty();
|
||||
}
|
||||
|
||||
public void setVisiable(boolean state) {
|
||||
this.visiable = state;
|
||||
public boolean isVisible() {
|
||||
return visible;
|
||||
}
|
||||
|
||||
public void setSelectedSet(Set<String> selectedSet) {
|
||||
this.selectedSet.clear();
|
||||
this.selectedSet.addAll(selectedSet);
|
||||
public void setVisible(boolean state) {
|
||||
this.visible = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("MissingData[");
|
||||
StringBuilder sb = new StringBuilder("LoadDisplayData[");
|
||||
sb.append("archive: ").append(archive);
|
||||
sb.append(", category: ").append(category);
|
||||
sb.append(", visible: ").append(visiable);
|
||||
sb.append(", visible: ").append(isVisible());
|
||||
sb.append(", isSelected: ").append(isSelected());
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
|
@ -815,14 +874,34 @@ public class SizeJob extends Job {
|
|||
* This handles getting the display data in the missing data queue and
|
||||
* queuing the results for the size job.
|
||||
*/
|
||||
private class MissingDataJob extends Job {
|
||||
private class LoadDisplayDataJob extends Job {
|
||||
|
||||
private final AtomicBoolean shutdown = new AtomicBoolean(false);
|
||||
|
||||
protected MissingData currentMissingData = null;
|
||||
protected LoadDisplayData currentLoadDisplayData = null;
|
||||
|
||||
public MissingDataJob() {
|
||||
super("MissingData");
|
||||
private final ILoadDisplayDataListener loadDisplayDataListener;
|
||||
|
||||
/**
|
||||
* Must be set to the maximum number of LoadDisplayData to process.
|
||||
* Cannot use the queue size since adjusting the queue to change the
|
||||
* priority may make its size 0. This could cause the job to be
|
||||
* rescheduled to finish when data added back onto the queue.
|
||||
*/
|
||||
private int loadDisplayDataCnt;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @param loadDisplayDataListener
|
||||
* @param loadDisplayDataCnt
|
||||
*/
|
||||
public LoadDisplayDataJob(
|
||||
ILoadDisplayDataListener loadDisplayDataListener,
|
||||
int loadDisplayDataCnt) {
|
||||
super("Loading Data Sets");
|
||||
this.loadDisplayDataListener = loadDisplayDataListener;
|
||||
this.loadDisplayDataCnt = loadDisplayDataCnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -834,20 +913,21 @@ public class SizeJob extends Job {
|
|||
ArchiveConfigManager manager = ArchiveConfigManager.getInstance();
|
||||
|
||||
while (!shutdown.get()) {
|
||||
synchronized (missingDataQueue) {
|
||||
if (currentMissingData != null) {
|
||||
missingDataQueue.notifyAll();
|
||||
synchronized (loadDisplayDataQueue) {
|
||||
if (currentLoadDisplayData != null) {
|
||||
currentLoadDisplayData = null;
|
||||
loadDisplayDataQueue.notifyAll();
|
||||
--loadDisplayDataCnt;
|
||||
}
|
||||
currentLoadDisplayData = loadDisplayDataQueue.poll();
|
||||
if (currentLoadDisplayData == null) {
|
||||
break;
|
||||
}
|
||||
currentMissingData = missingDataQueue.poll();
|
||||
}
|
||||
|
||||
if (currentMissingData == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
String archiveName = currentMissingData.archive;
|
||||
String categoryName = currentMissingData.category;
|
||||
Set<String> selectedSet = currentMissingData.selectedSet;
|
||||
String archiveName = currentLoadDisplayData.archive;
|
||||
String categoryName = currentLoadDisplayData.category;
|
||||
Set<String> selectedSet = currentLoadDisplayData.selectedSet;
|
||||
List<DisplayData> displayDatas = manager.getDisplayData(
|
||||
archiveName, categoryName, false);
|
||||
if (shutdown.get()) {
|
||||
|
@ -868,13 +948,31 @@ public class SizeJob extends Job {
|
|||
}
|
||||
}
|
||||
|
||||
if (loadDisplayDataCnt == 0) {
|
||||
if (loadDisplayDataListener != null) {
|
||||
loadDisplayDataListener.loadedAllDisplayData();
|
||||
}
|
||||
}
|
||||
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param loadDisplayData
|
||||
* @return true when missingData still needs to be processed.
|
||||
*/
|
||||
public boolean processing(LoadDisplayData loadDisplayData) {
|
||||
synchronized (loadDisplayDataQueue) {
|
||||
return loadDisplayDataQueue.contains(loadDisplayData)
|
||||
|| loadDisplayData.equals(currentLoadDisplayData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void canceling() {
|
||||
shutdown.set(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -22,6 +22,7 @@ package com.raytheon.uf.viz.archive.ui;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
@ -53,6 +54,7 @@ import com.raytheon.uf.common.util.SizeUtil;
|
|||
import com.raytheon.uf.viz.archive.data.ArchiveInfo;
|
||||
import com.raytheon.uf.viz.archive.data.CategoryInfo;
|
||||
import com.raytheon.uf.viz.archive.data.IArchiveTotals;
|
||||
import com.raytheon.uf.viz.archive.data.ILoadDisplayDataListener;
|
||||
import com.raytheon.uf.viz.archive.data.IRetentionHour;
|
||||
import com.raytheon.uf.viz.archive.data.IUpdateListener;
|
||||
import com.raytheon.uf.viz.archive.data.SizeJob;
|
||||
|
@ -77,6 +79,10 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* Aug 06, 2013 2222 rferrel Changes to display all selected data.
|
||||
* Nov 14, 2013 2549 rferrel Get category data moved off the UI thread.
|
||||
* Dec 11, 2013 2624 rferrel No longer clear table prior to populating.
|
||||
* Apr 15, 2014 3034 lvenable Added dispose checks in runAsync calls.
|
||||
* Apr 10, 2014 3023 rferrel Added setTotalSelectedSize method.
|
||||
* Apr 23, 2014 3045 rferrel Changes to prevent race condition while getting labels.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bgonzale
|
||||
|
@ -84,7 +90,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
*/
|
||||
|
||||
public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
||||
IArchiveTotals, IUpdateListener, IModifyListener, IRetentionHour {
|
||||
IArchiveTotals, IUpdateListener, IModifyListener, IRetentionHour,
|
||||
ILoadDisplayDataListener {
|
||||
|
||||
/** Table composite that holds the table controls. */
|
||||
private ArchiveTableComp tableComp;
|
||||
|
@ -112,7 +119,7 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
/**
|
||||
* Job that computes sizes of table row entries off the UI thread.
|
||||
*/
|
||||
protected final SizeJob sizeJob = new SizeJob();
|
||||
protected final SizeJob sizeJob = new SizeJob(this);
|
||||
|
||||
/** Keeps track of when it is safe to clear the busy cursor. */
|
||||
protected final AtomicInteger busyCnt = new AtomicInteger(0);
|
||||
|
@ -136,6 +143,9 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
|
||||
private String previousSelectedCategory = null;
|
||||
|
||||
/** Job running to populate the currently selected archive/category. */
|
||||
private Job populateTableJob = null;
|
||||
|
||||
/**
|
||||
* @param parentShell
|
||||
*/
|
||||
|
@ -362,6 +372,9 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
protected void disposed() {
|
||||
sizeJob.removeUpdateListener(this);
|
||||
sizeJob.cancel();
|
||||
if (populateTableJob != null) {
|
||||
populateTableJob.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,12 +473,17 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
}
|
||||
|
||||
/**
|
||||
* Load a select configuration file.
|
||||
* Load selected configuration file.
|
||||
*
|
||||
* @param selectName
|
||||
*/
|
||||
protected void loadSelect(String selectName) {
|
||||
sizeJob.loadSelect(selectName, type);
|
||||
protected boolean loadSelect(String selectName) {
|
||||
String message = sizeJob.loadSelect(selectName, type);
|
||||
if (message != null) {
|
||||
MessageDialog.openError(shell, "Unable to load Case", message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -480,15 +498,39 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
|
||||
setShowingSelected(false);
|
||||
|
||||
Job job = new Job("populate category table") {
|
||||
if (populateTableJob != null) {
|
||||
populateTableJob.cancel();
|
||||
setCursorBusy(false);
|
||||
}
|
||||
|
||||
populateTableJob = new Job("populate category table") {
|
||||
private AtomicBoolean shutdown = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
getCategoryTableData(archiveName, categoryName);
|
||||
getCategoryTableData(archiveName, categoryName, shutdown);
|
||||
|
||||
// Just populated the current table update cursor.
|
||||
if (!shutdown.get()) {
|
||||
populateTableJob = null;
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
setCursorBusy(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void canceling() {
|
||||
shutdown.set(true);
|
||||
}
|
||||
|
||||
};
|
||||
job.schedule();
|
||||
populateTableJob.schedule();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -498,26 +540,40 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
*
|
||||
* @param archiveName
|
||||
* @param categoryName
|
||||
* @param shutdown
|
||||
*/
|
||||
private void getCategoryTableData(final String archiveName,
|
||||
final String categoryName) {
|
||||
final String categoryName, final AtomicBoolean shutdown) {
|
||||
|
||||
if (!sizeJob.isCurrentDisplay(archiveName, categoryName)) {
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isDisposed()) {
|
||||
tableComp.clearTable();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final List<DisplayData> displayDatas = sizeJob.changeDisplay(
|
||||
archiveName, categoryName);
|
||||
archiveName, categoryName, shutdown);
|
||||
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (displayDatas != null) {
|
||||
tableComp.populateTable(archiveName, categoryName,
|
||||
displayDatas);
|
||||
} else {
|
||||
tableComp.refresh();
|
||||
}
|
||||
} finally {
|
||||
setCursorBusy(false);
|
||||
// If the dialog has been disposed then return.
|
||||
if (isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (displayDatas != null) {
|
||||
tableComp.populateTable(archiveName, categoryName,
|
||||
displayDatas);
|
||||
} else {
|
||||
tableComp.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -529,11 +585,14 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
* @param state
|
||||
*/
|
||||
protected void setCursorBusy(boolean state) {
|
||||
if (state) {
|
||||
busyCnt.addAndGet(1);
|
||||
shell.setCursor(shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
|
||||
} else if (busyCnt.addAndGet(-1) == 0) {
|
||||
shell.setCursor(null);
|
||||
if (!shell.isDisposed()) {
|
||||
if (state) {
|
||||
busyCnt.addAndGet(1);
|
||||
shell.setCursor(shell.getDisplay().getSystemCursor(
|
||||
SWT.CURSOR_WAIT));
|
||||
} else if (busyCnt.addAndGet(-1) == 0) {
|
||||
shell.setCursor(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -570,15 +629,22 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
}
|
||||
}
|
||||
|
||||
setTotalSelectedSize(totalSize);
|
||||
setTotalSelectedItems(totalSelected);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param selectedTotalSize
|
||||
*/
|
||||
protected void setTotalSelectedSize(long selectedTotalSize) {
|
||||
String sizeMsg = null;
|
||||
if (totalSize == DisplayData.UNKNOWN_SIZE) {
|
||||
if (selectedTotalSize == DisplayData.UNKNOWN_SIZE) {
|
||||
sizeMsg = DisplayData.UNKNOWN_SIZE_LABEL;
|
||||
} else {
|
||||
sizeMsg = SizeUtil.prettyByteSize(totalSize);
|
||||
sizeMsg = SizeUtil.prettyByteSize(selectedTotalSize);
|
||||
}
|
||||
|
||||
setTotalSizeText(sizeMsg);
|
||||
setTotalSelectedItems(totalSelected);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -676,6 +742,11 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
// If the dialog has been disposed then return.
|
||||
if (isDisposed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
tableComp.updateSize(myDisplayDatas);
|
||||
updateTotals(null);
|
||||
}
|
||||
|
@ -766,6 +837,11 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements
|
|||
return errorMsg == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows sub-class to perform updates once all the display data is loaded.
|
||||
*/
|
||||
abstract public void loadedAllDisplayData();
|
||||
|
||||
/**
|
||||
* When unsaved modifications this asks the user to verify the close.
|
||||
*
|
||||
|
|
|
@ -56,6 +56,8 @@ import com.raytheon.uf.common.time.util.TimeUtil;
|
|||
* Aug 26, 2013 #2225 rferrel Make dialog perspective independent.
|
||||
* Oct 01, 2013 #2147 rferrel Change getEnd() to pick up files with future time stamps.
|
||||
* Oct 07, 2013 #2438 rferrel Properly save and load retention times.
|
||||
* Apr 14, 2014 #3023 rferrel Code clean up.
|
||||
* Apr 24, 2014 #3045 rferrel Implement loadedAllDsipalyData.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -70,12 +72,6 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg {
|
|||
/** Current Archive/Category selection's extended retention hours. */
|
||||
private RetentionHours extRetention;
|
||||
|
||||
/** Displays the total number of selected items for all tables. */
|
||||
private Label totalSelectedItems;
|
||||
|
||||
/** Displays the total size of selected items. */
|
||||
private Label totalSizeLbl;
|
||||
|
||||
/** Flag to indicate when retention hours are modified. */
|
||||
private boolean retentionHoursAreModified = false;
|
||||
|
||||
|
@ -293,9 +289,6 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg {
|
|||
*/
|
||||
@Override
|
||||
protected void setTotalSizeText(String sizeStringText) {
|
||||
if (totalSizeLbl != null && !totalSizeLbl.isDisposed()) {
|
||||
totalSizeLbl.setText(sizeStringText);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -307,9 +300,6 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg {
|
|||
*/
|
||||
@Override
|
||||
protected void setTotalSelectedItems(int totalSize) {
|
||||
if (totalSelectedItems != null && !totalSelectedItems.isDisposed()) {
|
||||
totalSelectedItems.setText("" + totalSize);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -426,4 +416,9 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg {
|
|||
archiveComboSelection();
|
||||
categoryComboSelection();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadedAllDisplayData() {
|
||||
// nothing to update.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.archive.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
@ -63,6 +64,7 @@ import com.raytheon.uf.viz.archive.data.SizeJob;
|
|||
* Aug 06, 2013 #2222 rferrel Changes to display all selected data.
|
||||
* Aug 14, 2013 #2220 rferrel Add refresh method.
|
||||
* Aug 26, 2013 #2225 rferrel Add missing updates.
|
||||
* Apr 23, 2014 #3045 rferrel Added clearTable method and new column name.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -71,12 +73,19 @@ import com.raytheon.uf.viz.archive.data.SizeJob;
|
|||
*/
|
||||
public class ArchiveTableComp extends Composite {
|
||||
|
||||
/** Column label when table displaying category information. */
|
||||
private final String CATEGORY_COL_LABEL = "Data Set";
|
||||
|
||||
/** Column label when table displaying select all information. */
|
||||
private final String SEL_ALL_COL_LABEL = "Archive | Category | Data Set";
|
||||
|
||||
/** Column to display label information. */
|
||||
private final int LABEL_COL_INDEX = 0;
|
||||
|
||||
/** Column to display size information,. */
|
||||
private final int SIZE_COL_INDEX = 1;
|
||||
|
||||
/** Flag to indicate all selections are being displayed. */
|
||||
private boolean showSelectAll = false;
|
||||
|
||||
/** Name of table's archive. */
|
||||
|
@ -205,7 +214,7 @@ public class ArchiveTableComp extends Composite {
|
|||
});
|
||||
|
||||
TableColumn pathColumn = new TableColumn(table, SWT.LEFT);
|
||||
pathColumn.setText("Label");
|
||||
pathColumn.setText(CATEGORY_COL_LABEL);
|
||||
|
||||
TableColumn sizeColumn = new TableColumn(table, SWT.CENTER);
|
||||
if (type == Type.Retention) {
|
||||
|
@ -464,10 +473,17 @@ public class ArchiveTableComp extends Composite {
|
|||
protected void populateTable(String archiveName, String categoryName,
|
||||
List<DisplayData> displayDatas) {
|
||||
showSelectAll = false;
|
||||
table.getColumn(0).setText("Label");
|
||||
table.getColumn(0).setText(CATEGORY_COL_LABEL);
|
||||
populateTable(displayDatas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear table entries.
|
||||
*/
|
||||
protected void clearTable() {
|
||||
populateTable(new ArrayList<DisplayData>(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag table as showing all selected data and update display.
|
||||
*
|
||||
|
@ -475,7 +491,7 @@ public class ArchiveTableComp extends Composite {
|
|||
*/
|
||||
protected void populateSelectAll(List<DisplayData> displayDatas) {
|
||||
showSelectAll = true;
|
||||
table.getColumn(0).setText("Archive | Category | Label");
|
||||
table.getColumn(0).setText(SEL_ALL_COL_LABEL);
|
||||
populateTable(displayDatas);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.archive.ui;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* Archive case creation dialog's configuration options.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2014 3023 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
@XmlRootElement(name = "CaseCreation")
|
||||
@XmlAccessorType(XmlAccessType.NONE)
|
||||
public class CaseCreation {
|
||||
@XmlElement(name = "CautionThreshold")
|
||||
private float cautionThreshold;
|
||||
|
||||
@XmlElement(name = "DangerThreshold")
|
||||
private float dangerThreshold;
|
||||
|
||||
@XmlElement(name = "FatalThreshold")
|
||||
private float fatalThreshold;
|
||||
|
||||
public float getCautionThreshold() {
|
||||
return cautionThreshold;
|
||||
}
|
||||
|
||||
public void setCautionThreshold(float cautionThreshold) {
|
||||
this.cautionThreshold = cautionThreshold;
|
||||
}
|
||||
|
||||
public float getDangerThreshold() {
|
||||
return dangerThreshold;
|
||||
}
|
||||
|
||||
public void setDangerThreshold(float dangerThreshold) {
|
||||
this.dangerThreshold = dangerThreshold;
|
||||
}
|
||||
|
||||
public float getFatalThreshold() {
|
||||
return fatalThreshold;
|
||||
}
|
||||
|
||||
public void setFatalThreshold(float fatalThreshold) {
|
||||
this.fatalThreshold = fatalThreshold;
|
||||
}
|
||||
}
|
|
@ -75,6 +75,9 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback;
|
|||
* Aug 26, 2013 #2225 rferrel Make perspective independent and no longer modal.
|
||||
* Mar 24, 2014 #2853 rferrel Populate case label directory with default value.
|
||||
* Mar 26, 2014 32880 rferrerl Implement case compression and split.
|
||||
* Apr 11, 2014 #3023 rferrel Configurable Threshold options.
|
||||
* Apr 23, 2014 #3045 rferrel To prevent race condition only allow a case
|
||||
* load after all labels are loaded.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -165,6 +168,12 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
/** Allow only single instance of dialog. */
|
||||
private GenerateCaseDlg generateCaseDlg;
|
||||
|
||||
/** Manager for configurable values for the dialog. */
|
||||
private final CaseCreationManager ccManager;
|
||||
|
||||
/** Flag to indicate all labels for all tables are loaded. */
|
||||
private volatile boolean haveAllLabels = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -179,6 +188,7 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
this.setSelect = false;
|
||||
this.type = Type.Case;
|
||||
this.defaultCaseDir = defaultCaseDir;
|
||||
this.ccManager = new CaseCreationManager();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -487,34 +497,48 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
// }
|
||||
// });
|
||||
|
||||
String tooltip = "Waiting on loading of Data Sets.";
|
||||
Color color = shell.getDisplay().getSystemColor(SWT.COLOR_YELLOW);
|
||||
saveBtn = new Button(actionControlComp, SWT.PUSH);
|
||||
saveBtn.setText(" Save ");
|
||||
saveBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent selectionEvent) {
|
||||
saveSelection(selectName);
|
||||
clearModified();
|
||||
if (haveAllLabels) {
|
||||
saveSelection(selectName);
|
||||
clearModified();
|
||||
}
|
||||
}
|
||||
});
|
||||
saveBtn.setToolTipText(tooltip);
|
||||
saveBtn.setEnabled(false);
|
||||
saveBtn.setBackground(color);
|
||||
|
||||
saveAsBtn = new Button(actionControlComp, SWT.PUSH);
|
||||
saveAsBtn.setText(" Save As... ");
|
||||
saveAsBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent selectionEvent) {
|
||||
handleSaveAsCase();
|
||||
if (haveAllLabels) {
|
||||
handleSaveAsCase();
|
||||
}
|
||||
}
|
||||
});
|
||||
saveAsBtn.setToolTipText(tooltip);
|
||||
saveAsBtn.setBackground(color);
|
||||
|
||||
loadBtn = new Button(actionControlComp, SWT.PUSH);
|
||||
loadBtn.setText(" Load... ");
|
||||
loadBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent selectionEvent) {
|
||||
handleLoadCase();
|
||||
if (haveAllLabels) {
|
||||
handleLoadCase();
|
||||
}
|
||||
}
|
||||
});
|
||||
loadBtn.setToolTipText(tooltip);
|
||||
loadBtn.setBackground(color);
|
||||
|
||||
deleteBtn = new Button(actionControlComp, SWT.PUSH);
|
||||
deleteBtn.setText(" Delete... ");
|
||||
|
@ -603,11 +627,12 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
public void dialogClosed(Object returnValue) {
|
||||
if (returnValue instanceof String) {
|
||||
String name = returnValue.toString();
|
||||
loadSelect(name);
|
||||
populateTableComp();
|
||||
updateTotals(null);
|
||||
setSelectName(name);
|
||||
clearModified();
|
||||
if (loadSelect(name)) {
|
||||
populateTableComp();
|
||||
updateTotals(null);
|
||||
setSelectName(name);
|
||||
clearModified();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -832,24 +857,33 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
if (isDisposed()) {
|
||||
return;
|
||||
}
|
||||
File dir = (File) locationLbl.getData();
|
||||
Object o = locationLbl.getData();
|
||||
if (!(o instanceof File)) {
|
||||
return;
|
||||
}
|
||||
File dir = (File) o;
|
||||
long totSpace = dir.getTotalSpace();
|
||||
long freeSpace = dir.getUsableSpace();
|
||||
|
||||
o = uncompressSizeLbl.getData();
|
||||
if (o instanceof Long) {
|
||||
freeSpace -= (Long) o;
|
||||
}
|
||||
long percentFull = (long) Math.round(((totSpace - freeSpace) * 100.0)
|
||||
/ totSpace);
|
||||
String state = null;
|
||||
Color bgColor = null;
|
||||
Color fgColor = null;
|
||||
Display display = shell.getDisplay();
|
||||
if (percentFull <= 84) {
|
||||
if (freeSpace > ccManager.getCautionThreshold()) {
|
||||
state = "GOOD";
|
||||
bgColor = display.getSystemColor(SWT.COLOR_GREEN);
|
||||
fgColor = display.getSystemColor(SWT.COLOR_BLACK);
|
||||
} else if (percentFull <= 94) {
|
||||
} else if (freeSpace > ccManager.getDangerThreshold()) {
|
||||
state = "CAUTION";
|
||||
bgColor = display.getSystemColor(SWT.COLOR_YELLOW);
|
||||
fgColor = display.getSystemColor(SWT.COLOR_BLACK);
|
||||
} else if (percentFull <= 97) {
|
||||
} else if (freeSpace > ccManager.getFatalThreshold()) {
|
||||
state = "DANGER";
|
||||
bgColor = display.getSystemColor(SWT.COLOR_RED);
|
||||
fgColor = display.getSystemColor(SWT.COLOR_BLACK);
|
||||
|
@ -958,10 +992,46 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#setTotalSizeText(java
|
||||
* .lang.String)
|
||||
*/
|
||||
@Override
|
||||
protected void setTotalSizeText(String text) {
|
||||
uncompressSizeLbl.setText(text);
|
||||
if (!uncompressSizeLbl.isDisposed()) {
|
||||
uncompressSizeLbl.setText(text);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#setTotalSelectedSize
|
||||
* (long)
|
||||
*/
|
||||
@Override
|
||||
protected void setTotalSelectedSize(long totalSize) {
|
||||
super.setTotalSelectedSize(totalSize);
|
||||
Long tSize = null;
|
||||
if (totalSize > 0) {
|
||||
tSize = new Long(totalSize);
|
||||
}
|
||||
uncompressSizeLbl.setData(tSize);
|
||||
updateLocationState();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#setTotalSelectedItems
|
||||
* (int)
|
||||
*/
|
||||
@Override
|
||||
protected void setTotalSelectedItems(int totalSelected) {
|
||||
selectedItemsSize = totalSelected;
|
||||
totalSelectedItemsLbl.setText("" + totalSelected);
|
||||
|
@ -1034,4 +1104,40 @@ public class CaseCreationDlg extends AbstractArchiveDlg {
|
|||
defaultCaseDir));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#haveAllLabels()
|
||||
*/
|
||||
@Override
|
||||
public void loadedAllDisplayData() {
|
||||
haveAllLabels = true;
|
||||
|
||||
/*
|
||||
* Restore the buttons' default background color and tooltip text. The
|
||||
* buttons color is not the system standard and the tool tip text
|
||||
* indicates it is waiting for the labels to be loaded.
|
||||
*/
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (!isDisposed()) {
|
||||
saveBtn.setBackground(null);
|
||||
saveBtn.setToolTipText(null);
|
||||
saveAsBtn.setBackground(null);
|
||||
saveAsBtn.setToolTipText(null);
|
||||
loadBtn.setBackground(null);
|
||||
loadBtn.setToolTipText(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isModified() {
|
||||
return super.isModified();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.archive.ui;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import javax.xml.bind.JAXB;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import com.raytheon.uf.common.localization.IPathManager;
|
||||
import com.raytheon.uf.common.localization.PathManagerFactory;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
||||
/**
|
||||
* This class obtains the configurable options for the archive case creation
|
||||
* dialog.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2014 3023 rferrel Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author rferrel
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class CaseCreationManager {
|
||||
private static transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(CaseCreationManager.class);
|
||||
|
||||
private CaseCreation caseCreation;
|
||||
|
||||
public CaseCreationManager() {
|
||||
initValues();
|
||||
}
|
||||
|
||||
private void initValues() {
|
||||
String path = "archiver" + IPathManager.SEPARATOR + "gui"
|
||||
+ IPathManager.SEPARATOR + "CaseCreation.xml";
|
||||
IPathManager pm = PathManagerFactory.getPathManager();
|
||||
File file = pm.getStaticFile(path);
|
||||
try {
|
||||
caseCreation = JAXB.unmarshal(file, CaseCreation.class);
|
||||
} catch (RuntimeException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), e);
|
||||
caseCreation = new CaseCreation();
|
||||
}
|
||||
|
||||
if (caseCreation.getCautionThreshold() <= 0.0) {
|
||||
caseCreation.setCautionThreshold((float) 2.0);
|
||||
}
|
||||
|
||||
if (caseCreation.getDangerThreshold() <= 0.0) {
|
||||
caseCreation.setDangerThreshold((float) 1.0);
|
||||
}
|
||||
|
||||
if (caseCreation.getFatalThreshold() <= 0.0) {
|
||||
caseCreation.setFatalThreshold((float) 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
public long getCautionThreshold() {
|
||||
return (long) (caseCreation.getCautionThreshold() * FileUtils.ONE_GB);
|
||||
}
|
||||
|
||||
public long getDangerThreshold() {
|
||||
return (long) (caseCreation.getDangerThreshold() * FileUtils.ONE_GB);
|
||||
}
|
||||
|
||||
public long getFatalThreshold() {
|
||||
return (long) (caseCreation.getFatalThreshold() * FileUtils.ONE_GB);
|
||||
}
|
||||
}
|
|
@ -116,7 +116,7 @@ public class CaseLoadSaveDeleteDlg extends CaveSWTDialog {
|
|||
private void init() {
|
||||
createCaseControls();
|
||||
GuiUtil.addSeparator(shell, SWT.HORIZONTAL);
|
||||
createBottomAcitonButtons();
|
||||
createBottomActionButtons();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -151,7 +151,7 @@ public class CaseLoadSaveDeleteDlg extends CaveSWTDialog {
|
|||
/**
|
||||
* Button layout at the bottom of the dialog.
|
||||
*/
|
||||
private void createBottomAcitonButtons() {
|
||||
private void createBottomActionButtons() {
|
||||
Composite actionControlComp = new Composite(shell, SWT.NONE);
|
||||
GridLayout gl = new GridLayout(2, false);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
|
|
|
@ -27,8 +27,13 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
|
@ -60,6 +65,9 @@ import org.eclipse.swt.widgets.Shell;
|
|||
import com.raytheon.uf.common.archive.config.ArchiveConfigManager;
|
||||
import com.raytheon.uf.common.archive.config.ArchiveConstants;
|
||||
import com.raytheon.uf.common.archive.config.DisplayData;
|
||||
import com.raytheon.uf.common.dataquery.requests.SharedLockRequest;
|
||||
import com.raytheon.uf.common.dataquery.requests.SharedLockRequest.RequestType;
|
||||
import com.raytheon.uf.common.dataquery.responses.SharedLockResponse;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
@ -67,10 +75,12 @@ import com.raytheon.uf.common.time.util.ITimer;
|
|||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.FileUtil;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||
|
||||
/**
|
||||
* This class performs the desired type of case creation and display a
|
||||
* This class performs the desired type of case creation and displays a
|
||||
* progress/status message dialog.
|
||||
*
|
||||
* <pre>
|
||||
|
@ -84,8 +94,9 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* archive and category directory and
|
||||
* implementation of compression.
|
||||
* Oct 08, 2013 2442 rferrel Remove category directory.
|
||||
* Feb 04, 2013 2270 rferrel Move HDF files to parent's directory.
|
||||
* Feb 04, 2014 2270 rferrel Move HDF files to parent's directory.
|
||||
* Mar 26, 2014 2880 rferrel Compress and split cases implemented.
|
||||
* Apr 03, 2014 2862 rferrel Logic for shared locking of top level directories.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -95,12 +106,12 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
|
||||
public class GenerateCaseDlg extends CaveSWTDialog {
|
||||
|
||||
/** Extension for HDF files. */
|
||||
private static final String hdfExt = ".h5";
|
||||
|
||||
private final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(GenerateCaseDlg.class);
|
||||
|
||||
/** Extension for HDF files. */
|
||||
private static final String hdfExt = ".h5";
|
||||
|
||||
/** Use to display the current state of the case generation. */
|
||||
private Label stateLbl;
|
||||
|
||||
|
@ -125,7 +136,7 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
/** End time for the case. */
|
||||
private final Calendar endCal;
|
||||
|
||||
/** Data list for the case. */
|
||||
/** Data list for the case sorted by archive and category names. */
|
||||
private final DisplayData[] sourceDataList;
|
||||
|
||||
/** When true compress the case directory. */
|
||||
|
@ -374,24 +385,74 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
}
|
||||
|
||||
/**
|
||||
* The performs the work of generating the case on a non-UI thread.
|
||||
* This performs the work of generating the case on a non-UI thread.
|
||||
*/
|
||||
private class GenerateJob extends Job {
|
||||
/** Parent flag to shutdown the job. */
|
||||
private final AtomicBoolean shutdown = new AtomicBoolean(false);
|
||||
|
||||
/** How long to wait before making another request for a plug-in lock. */
|
||||
private final long LOCK_RETRY_TIME = 2 * TimeUtil.MILLIS_PER_MINUTE;
|
||||
|
||||
/** Files/directories needing plug-in locks in order to copy. */
|
||||
private final Map<CopyInfo, Map<String, List<File>>> caseCopyMap = new HashMap<CopyInfo, Map<String, List<File>>>();
|
||||
|
||||
/** Timer to determine when to send another request for a plug-in lock. */
|
||||
private final ITimer retrytimer = TimeUtil.getTimer();
|
||||
|
||||
/** Timer to update current lock's last execute time. */
|
||||
private Timer updateTimer = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public GenerateJob() {
|
||||
super("Generate Case");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
if (monitor.isCanceled()) {
|
||||
return Status.OK_STATUS;
|
||||
/**
|
||||
* Add file to the caseCopyMap.
|
||||
*
|
||||
* @param copyInfo
|
||||
* @param plugin
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
private boolean putFile(CopyInfo copyInfo, String plugin, File file) {
|
||||
if (caseCopyMap.size() == 0) {
|
||||
retrytimer.start();
|
||||
}
|
||||
|
||||
Map<String, List<File>> pluginMap = caseCopyMap.get(copyInfo);
|
||||
|
||||
if (pluginMap == null) {
|
||||
pluginMap = new HashMap<String, List<File>>();
|
||||
caseCopyMap.put(copyInfo, pluginMap);
|
||||
}
|
||||
|
||||
List<File> files = pluginMap.get(plugin);
|
||||
|
||||
if (files == null) {
|
||||
files = new ArrayList<File>();
|
||||
pluginMap.put(plugin, files);
|
||||
}
|
||||
return files.add(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param copyInfo
|
||||
* @return true if locks needed to complete the copy.
|
||||
*/
|
||||
private boolean keepCaseCopy(CopyInfo copyInfo) {
|
||||
return caseCopyMap.get(copyInfo) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when valid case directory.
|
||||
*/
|
||||
private boolean validateCaseDirectory() {
|
||||
setStateLbl("Creating: " + caseDir.getName(),
|
||||
caseDir.getAbsolutePath());
|
||||
ICaseCopy caseCopy = null;
|
||||
|
||||
String errorMessage = null;
|
||||
if (caseDir.exists()) {
|
||||
|
@ -403,41 +464,98 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
if (errorMessage != null) {
|
||||
setStateLbl(errorMessage, caseDir.getAbsolutePath());
|
||||
setProgressBar(100, SWT.ERROR);
|
||||
return Status.OK_STATUS;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shutdown.get()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.
|
||||
* IProgressMonitor)
|
||||
*/
|
||||
@Override
|
||||
protected IStatus run(IProgressMonitor monitor) {
|
||||
if (monitor.isCanceled()) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
if (!validateCaseDirectory()) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
ICaseCopy caseCopy = null;
|
||||
String currentArchive = null;
|
||||
String currentCategory = null;
|
||||
boolean updateDestDir = false;
|
||||
int rootDirLen = -1;
|
||||
File rootDir = null;
|
||||
String plugin = null;
|
||||
boolean allowCopy = true;
|
||||
CopyInfo copyInfo = null;
|
||||
|
||||
ITimer timer = TimeUtil.getTimer();
|
||||
timer.start();
|
||||
|
||||
try {
|
||||
/*
|
||||
* The sourceDataList is sorted so all the displayDatas for a
|
||||
* given archive/category are grouped together in the loop.
|
||||
*/
|
||||
for (DisplayData displayData : sourceDataList) {
|
||||
if (shutdown.get()) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
if (!displayData.getArchiveName().equals(currentArchive)) {
|
||||
updateDestDir = true;
|
||||
/*
|
||||
* The current display data is for a different
|
||||
* archive/category then the previous one.
|
||||
*/
|
||||
if (!displayData.getArchiveName().equals(currentArchive)
|
||||
|| !displayData.getCategoryName().equals(
|
||||
currentCategory)) {
|
||||
|
||||
// Finish up previous archive/category.
|
||||
if (caseCopy != null) {
|
||||
if (allowCopy) {
|
||||
releaseLock(plugin);
|
||||
}
|
||||
|
||||
/*
|
||||
* The copyInfo needs locks in order to finish.
|
||||
* Force creation of a new caseCopy for the new
|
||||
* category.
|
||||
*/
|
||||
if (keepCaseCopy(copyInfo)) {
|
||||
caseCopy = null;
|
||||
copyInfo = null;
|
||||
} else {
|
||||
caseCopy.finishCase();
|
||||
}
|
||||
plugin = null;
|
||||
}
|
||||
|
||||
// Set up for new category.
|
||||
currentArchive = displayData.getArchiveName();
|
||||
currentCategory = displayData.getCategoryName();
|
||||
} else if (!displayData.getCategoryName().equals(
|
||||
currentCategory)) {
|
||||
updateDestDir = true;
|
||||
currentCategory = displayData.getCategoryName();
|
||||
}
|
||||
rootDir = new File(displayData.getRootDir());
|
||||
rootDirLen = displayData.getRootDir().length();
|
||||
allowCopy = true;
|
||||
|
||||
if (updateDestDir) {
|
||||
updateDestDir = false;
|
||||
if (caseCopy != null) {
|
||||
caseCopy.finishCase();
|
||||
} else {
|
||||
setStateLbl(currentArchive + " | " + currentCategory,
|
||||
caseDir.getAbsolutePath() + "\n"
|
||||
+ currentArchive + "\n"
|
||||
+ currentCategory);
|
||||
|
||||
/*
|
||||
* When caseCopy is not null it is safe to reuse it for
|
||||
* the new category.
|
||||
*/
|
||||
if (caseCopy == null) {
|
||||
if (!doCompress) {
|
||||
caseCopy = new CopyMove();
|
||||
} else if (doMultiFiles) {
|
||||
|
@ -445,33 +563,83 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
} else {
|
||||
caseCopy = new CompressCopy();
|
||||
}
|
||||
copyInfo = new CopyInfo(caseCopy, currentArchive,
|
||||
currentCategory, caseDir);
|
||||
}
|
||||
|
||||
caseCopy.startCase(caseDir, displayData, shutdown);
|
||||
setStateLbl(currentArchive + " | " + currentCategory,
|
||||
caseDir.getAbsolutePath() + "\n"
|
||||
+ currentArchive + "\n"
|
||||
+ currentCategory);
|
||||
}
|
||||
|
||||
List<File> files = archiveManager.getDisplayFiles(
|
||||
displayData, startCal, endCal);
|
||||
|
||||
/*
|
||||
* Check all files/directories in the displayData and
|
||||
* attempt a recursive copy.
|
||||
*/
|
||||
for (File source : files) {
|
||||
if (shutdown.get()) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
caseCopy.copy(source);
|
||||
String dirName = source.getAbsolutePath()
|
||||
.substring(rootDirLen).split(File.separator)[0];
|
||||
String newPlugin = (new File(rootDir, dirName))
|
||||
.getAbsolutePath();
|
||||
|
||||
// Have new plugin.
|
||||
if (!newPlugin.equals(plugin)) {
|
||||
// Release the current lock.
|
||||
if (allowCopy && (plugin != null)) {
|
||||
releaseLock(plugin);
|
||||
}
|
||||
allowCopy = requestLock(newPlugin);
|
||||
plugin = newPlugin;
|
||||
}
|
||||
|
||||
if (allowCopy) {
|
||||
// Have lock safe to perform recursive copy.
|
||||
caseCopy.copy(source);
|
||||
} else {
|
||||
// No lock add to Map of files needing locks.
|
||||
putFile(copyInfo, plugin, source);
|
||||
}
|
||||
} // End of files loop
|
||||
|
||||
/*
|
||||
* The copy may have taken some time see if any pending
|
||||
* copies can be completed.
|
||||
*/
|
||||
if (retrytimer.getElapsedTime() >= LOCK_RETRY_TIME) {
|
||||
retryCasesCopy();
|
||||
}
|
||||
}
|
||||
if (caseCopy != null) {
|
||||
caseCopy.finishCase();
|
||||
} // End of sourceDataList loop
|
||||
|
||||
// Finish up the loop's last plugin.
|
||||
if (plugin != null) {
|
||||
if (allowCopy) {
|
||||
releaseLock(plugin);
|
||||
}
|
||||
|
||||
// Finish last case
|
||||
if (!keepCaseCopy(copyInfo)) {
|
||||
caseCopy.finishCase();
|
||||
}
|
||||
plugin = null;
|
||||
}
|
||||
caseCopy = null;
|
||||
|
||||
// Finish pending copies needing locks.
|
||||
waitForLocks();
|
||||
|
||||
if (shutdown.get()) {
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
setStateLbl("Created: " + caseName, caseDir.getAbsolutePath());
|
||||
setProgressBar(100, SWT.NORMAL);
|
||||
|
||||
} catch (CaseCreateException e) {
|
||||
} catch (Exception e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
setStateLbl(
|
||||
|
@ -479,15 +647,25 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
caseDir.getAbsolutePath() + "\n"
|
||||
+ e.getLocalizedMessage());
|
||||
setProgressBar(100, SWT.ERROR);
|
||||
shutdown.set(true);
|
||||
} finally {
|
||||
if (caseCopy != null) {
|
||||
try {
|
||||
caseCopy.finishCase();
|
||||
} catch (Exception ex) {
|
||||
// Ignore
|
||||
}
|
||||
caseCopy = null;
|
||||
// shutdown the time.
|
||||
if (updateTimer != null) {
|
||||
updateTimer.cancel();
|
||||
updateTimer = null;
|
||||
}
|
||||
|
||||
// Release resources of active case copy.
|
||||
if (caseCopy != null) {
|
||||
if (!keepCaseCopy(copyInfo)) {
|
||||
try {
|
||||
// Allow the caseCopy to clean its resources.
|
||||
caseCopy.finishCase();
|
||||
} catch (Exception ex) {
|
||||
// Ignore
|
||||
}
|
||||
caseCopy = null;
|
||||
}
|
||||
timer.stop();
|
||||
if (statusHandler.isPriorityEnabled(Priority.INFO)) {
|
||||
String message = String.format("Case %s took %s.",
|
||||
|
@ -495,11 +673,201 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
TimeUtil.prettyDuration(timer.getElapsedTime()));
|
||||
statusHandler.handle(Priority.INFO, message);
|
||||
}
|
||||
}
|
||||
|
||||
// Release current lock.
|
||||
if (allowCopy && (plugin != null)) {
|
||||
releaseLock(plugin);
|
||||
}
|
||||
|
||||
// Release resources of any pending case copy.
|
||||
if (caseCopyMap.size() > 0) {
|
||||
for (CopyInfo cpi : caseCopyMap.keySet()) {
|
||||
try {
|
||||
cpi.caseCopy.finishCase();
|
||||
} catch (CaseCreateException ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
caseCopyMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish copying all files needing locks.
|
||||
*
|
||||
* @throws CaseCreateException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
private void waitForLocks() throws CaseCreateException,
|
||||
InterruptedException {
|
||||
int retryCount = 0;
|
||||
boolean updateStatus = true;
|
||||
while (caseCopyMap.size() > 0) {
|
||||
if (updateStatus) {
|
||||
++retryCount;
|
||||
StringBuilder tooltip = new StringBuilder();
|
||||
tooltip.append("Waiting to finish ").append(
|
||||
caseCopyMap.size());
|
||||
if (caseCopyMap.size() == 1) {
|
||||
tooltip.append(" category.");
|
||||
} else {
|
||||
tooltip.append(" categories.");
|
||||
}
|
||||
tooltip.append("\nAttempt: ").append(retryCount);
|
||||
setStateLbl("Waiting for locks", tooltip.toString());
|
||||
updateStatus = false;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
wait(TimeUtil.MILLIS_PER_SECOND / 2L);
|
||||
}
|
||||
|
||||
if (shutdown.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (retrytimer.getElapsedTime() >= LOCK_RETRY_TIME) {
|
||||
retryCasesCopy();
|
||||
updateStatus = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to copy files still waiting on plug-in locks.
|
||||
*
|
||||
* @throws CaseCreateException
|
||||
*/
|
||||
private void retryCasesCopy() throws CaseCreateException {
|
||||
if (shutdown.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (caseCopyMap.size() > 0) {
|
||||
retrytimer.stop();
|
||||
retrytimer.reset();
|
||||
String lockedPlugin = null;
|
||||
try {
|
||||
Iterator<CopyInfo> copyInfoIter = caseCopyMap.keySet()
|
||||
.iterator();
|
||||
while (copyInfoIter.hasNext()) {
|
||||
CopyInfo copyInfo = copyInfoIter.next();
|
||||
setStateLbl(copyInfo.archive + " | "
|
||||
+ copyInfo.category,
|
||||
copyInfo.caseDir.getAbsolutePath() + "\n"
|
||||
+ copyInfo.archive + "\n"
|
||||
+ copyInfo.category);
|
||||
|
||||
Map<String, List<File>> pluginMap = caseCopyMap
|
||||
.get(copyInfo);
|
||||
Iterator<String> pluginIter = pluginMap.keySet()
|
||||
.iterator();
|
||||
while (pluginIter.hasNext()) {
|
||||
String plugin = pluginIter.next();
|
||||
if (shutdown.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (requestLock(plugin)) {
|
||||
lockedPlugin = plugin;
|
||||
for (File source : pluginMap.get(plugin)) {
|
||||
copyInfo.caseCopy.copy(source);
|
||||
if (shutdown.get()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
releaseLock(plugin);
|
||||
lockedPlugin = null;
|
||||
pluginIter.remove();
|
||||
}
|
||||
}
|
||||
if (pluginMap.size() == 0) {
|
||||
copyInfo.caseCopy.finishCase();
|
||||
copyInfoIter.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (lockedPlugin != null) {
|
||||
releaseLock(lockedPlugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (caseCopyMap.size() > 0) {
|
||||
retrytimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a lock for the plug-in.
|
||||
*
|
||||
* @param details
|
||||
* @return true when lock obtained otherwise false
|
||||
*/
|
||||
private boolean requestLock(String details) {
|
||||
SharedLockRequest request = new SharedLockRequest(
|
||||
ArchiveConstants.CLUSTER_NAME, details,
|
||||
RequestType.READER_LOCK);
|
||||
|
||||
try {
|
||||
Object o = ThriftClient.sendRequest(request);
|
||||
if (o instanceof SharedLockResponse) {
|
||||
SharedLockResponse response = (SharedLockResponse) o;
|
||||
if (response.isSucessful()) {
|
||||
if (updateTimer == null) {
|
||||
updateTimer = new Timer(
|
||||
"Case Creation update timer", true);
|
||||
}
|
||||
TimerTask timerTask = new LockUpdateTask(details);
|
||||
updateTimer.schedule(timerTask,
|
||||
TimeUtil.MILLIS_PER_MINUTE,
|
||||
TimeUtil.MILLIS_PER_MINUTE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Release previously obtained lock for the details.
|
||||
*
|
||||
* @param details
|
||||
* @return true when lock released otherwise false.
|
||||
*/
|
||||
private boolean releaseLock(String details) {
|
||||
SharedLockRequest request = new SharedLockRequest(
|
||||
ArchiveConstants.CLUSTER_NAME, details,
|
||||
RequestType.READER_UNLOCK);
|
||||
try {
|
||||
if (updateTimer != null) {
|
||||
updateTimer.cancel();
|
||||
updateTimer = null;
|
||||
}
|
||||
Object o = ThriftClient.sendRequest(request);
|
||||
if (o instanceof SharedLockResponse) {
|
||||
SharedLockResponse response = (SharedLockResponse) o;
|
||||
if (response.isSucessful()) {
|
||||
details = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -574,7 +942,7 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
copyFile(new File(source, file),
|
||||
new File(destination, file));
|
||||
}
|
||||
} else {
|
||||
} else if (source.exists()) {
|
||||
// DR 2270 bump HDF files up a directory.
|
||||
if (destination.getName().endsWith(hdfExt)) {
|
||||
destination = new File(destination.getParentFile()
|
||||
|
@ -745,7 +1113,7 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
tarDirFile.add(file);
|
||||
addTarFiles(file.listFiles());
|
||||
}
|
||||
} else {
|
||||
} else if (file.exists()) {
|
||||
checkFit(file);
|
||||
// DR 2270 bump HDF files up a directory.
|
||||
if (name.endsWith(hdfExt)) {
|
||||
|
@ -1000,4 +1368,46 @@ public class GenerateCaseDlg extends CaveSWTDialog {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Task to update the lock plugin's last execute time. */
|
||||
private final class LockUpdateTask extends TimerTask {
|
||||
/** The locked cluster task's details. */
|
||||
private final String details;
|
||||
|
||||
public LockUpdateTask(String details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
SharedLockRequest request = new SharedLockRequest(
|
||||
ArchiveConstants.CLUSTER_NAME, details,
|
||||
RequestType.READER_UPDATE_TIME);
|
||||
try {
|
||||
ThriftClient.sendRequest(request);
|
||||
} catch (VizException e) {
|
||||
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Information needed to update status when retrying a copy. */
|
||||
private static class CopyInfo {
|
||||
protected final ICaseCopy caseCopy;
|
||||
|
||||
protected final String archive;
|
||||
|
||||
protected final String category;
|
||||
|
||||
protected final File caseDir;
|
||||
|
||||
public CopyInfo(ICaseCopy caseCopy, String archive, String category,
|
||||
File caseDir) {
|
||||
this.caseCopy = caseCopy;
|
||||
this.archive = archive;
|
||||
this.category = category;
|
||||
this.caseDir = caseDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Ccfp Plug-in
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.ccfp;singleton:=true
|
||||
Bundle-Version: 1.12.1174.qualifier
|
||||
Bundle-Activator: com.raytheon.uf.viz.ccfp.Activator
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Eclipse-RegisterBuddy: com.raytheon.viz.core, com.raytheon.uf.viz.core
|
||||
Require-Bundle: com.raytheon.uf.viz.core
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||
Import-Package: com.raytheon.edex.plugin.ccfp,
|
||||
com.raytheon.uf.common.dataplugin,
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Import-Package: com.raytheon.uf.common.dataplugin,
|
||||
com.raytheon.uf.common.dataplugin.ccfp,
|
||||
com.raytheon.uf.common.geospatial,
|
||||
com.raytheon.uf.common.status,
|
||||
com.raytheon.uf.common.time,
|
||||
|
@ -18,15 +18,9 @@ Import-Package: com.raytheon.edex.plugin.ccfp,
|
|||
com.raytheon.uf.viz.core.map,
|
||||
com.raytheon.uf.viz.core.rsc,
|
||||
com.raytheon.uf.viz.core.rsc.capabilities,
|
||||
com.raytheon.uf.viz.core.status,
|
||||
com.vividsolutions.jts.geom,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.swt.graphics,
|
||||
org.eclipse.ui.plugin,
|
||||
org.opengis.referencing.crs,
|
||||
org.osgi.framework
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.raytheon.uf.viz.core,
|
||||
org.geotools;bundle-version="2.5.2"
|
||||
Export-Package: com.raytheon.uf.viz.ccfp,
|
||||
com.raytheon.uf.viz.ccfp.rsc
|
||||
Export-Package: com.raytheon.uf.viz.ccfp.rsc
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.ccfp;
|
||||
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Sep 22, 2009 3072 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class Activator extends AbstractUIPlugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "com.raytheon.uf.viz.ccfp";
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,8 +32,8 @@ import org.eclipse.swt.graphics.RGB;
|
|||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.opengis.referencing.crs.CoordinateReferenceSystem;
|
||||
|
||||
import com.raytheon.edex.plugin.ccfp.CcfpRecord;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.ccfp.CcfpRecord;
|
||||
import com.raytheon.uf.common.geospatial.ReferencedCoordinate;
|
||||
import com.raytheon.uf.common.time.DataTime;
|
||||
import com.raytheon.uf.viz.core.IExtent;
|
||||
|
|
|
@ -25,8 +25,8 @@ import javax.xml.bind.annotation.XmlAccessType;
|
|||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlAttribute;
|
||||
|
||||
import com.raytheon.edex.plugin.ccfp.CcfpRecord;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.dataplugin.ccfp.CcfpRecord;
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Collaboratioin
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.collaboration.comm;singleton:=true
|
||||
Bundle-Version: 1.13.0.qualifier
|
||||
Bundle-Version: 1.14.0.qualifier
|
||||
Bundle-Activator: com.raytheon.uf.viz.collaboration.comm.Activator
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Eclipse-RegisterBuddy: com.raytheon.uf.viz.core
|
||||
|
@ -32,6 +32,8 @@ Export-Package: com.raytheon.uf.viz.collaboration.comm,
|
|||
com.raytheon.uf.viz.collaboration.comm.identity.user,
|
||||
com.raytheon.uf.viz.collaboration.comm.packet,
|
||||
com.raytheon.uf.viz.collaboration.comm.provider,
|
||||
com.raytheon.uf.viz.collaboration.comm.provider.account,
|
||||
com.raytheon.uf.viz.collaboration.comm.provider.connection,
|
||||
com.raytheon.uf.viz.collaboration.comm.provider.event,
|
||||
com.raytheon.uf.viz.collaboration.comm.provider.info,
|
||||
com.raytheon.uf.viz.collaboration.comm.provider.session,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
|
@ -34,6 +35,7 @@ import com.raytheon.uf.common.comm.NetworkStatistics;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 27, 2012 jkorman Initial creation
|
||||
* Apr 23, 2014 2822 bclement added getBundleVersion()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -80,4 +82,20 @@ public class Activator implements BundleActivator {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version from the manifest
|
||||
*
|
||||
* @return null if not available
|
||||
*/
|
||||
public static String getBundleVersion(){
|
||||
String rval = null;
|
||||
if ( plugin != null){
|
||||
BundleContext context = plugin.getContext();
|
||||
if ( context != null){
|
||||
Bundle bundle = context.getBundle();
|
||||
rval = bundle.getVersion().toString();
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ 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.IUser;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
|
||||
/**
|
||||
* Base interface for sessions in which the client is interacting with others on
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
|||
* Feb 13, 2014 2751 bclement changed sendObjectToPeer id to VenueParticipant
|
||||
* Feb 13, 2014 2751 njensen Added changeLeader()
|
||||
* Feb 19, 2014 2751 bclement Added isClosed()
|
||||
* Apr 15, 2014 2822 bclement added isSharedDisplayClient()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -124,4 +125,10 @@ public interface ISharedDisplaySession extends IVenueSession {
|
|||
*/
|
||||
public boolean isClosed();
|
||||
|
||||
/**
|
||||
* @param participant
|
||||
* @return true if the participant is viewing the shared display
|
||||
*/
|
||||
public boolean isSharedDisplayClient(VenueParticipant participant);
|
||||
|
||||
}
|
||||
|
|
|
@ -19,9 +19,10 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.identity.event;
|
||||
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
||||
/**
|
||||
* Event fired when the roster has changed
|
||||
*
|
||||
|
@ -33,6 +34,7 @@ import org.jivesoftware.smack.packet.Presence;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 06, 2012 jkorman Initial creation.
|
||||
* Feb 24, 2014 2632 mpduff Added getPresence, changed getItem to getEntry.
|
||||
* Apr 24, 2014 3070 bclement getEntry() returns UserId
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -54,7 +56,7 @@ public interface IRosterChangeEvent {
|
|||
*
|
||||
* @return The changed entry
|
||||
*/
|
||||
RosterEntry getEntry();
|
||||
UserId getEntry();
|
||||
|
||||
/**
|
||||
* Get the Presence object.
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.identity.roster;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.ISubscriptionRequestCompleteAction;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.account.ISubscriptionRequestCompleteAction;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.account;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
@ -34,6 +34,7 @@ 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.provider.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserPresenceChangedEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
||||
|
@ -60,6 +61,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Feb 12, 2014 2797 bclement added protective copy to sendPresence
|
||||
* Feb 13, 2014 2755 bclement added user input for which group to add contact to
|
||||
* Apr 07, 2014 2785 mpduff Moved PacketListener implementation to its own class
|
||||
* Apr 14, 2014 2903 bclement moved from session subpackage to account, made constructor public
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -81,7 +83,7 @@ public class AccountManager implements IAccountManager {
|
|||
*
|
||||
* @param adapter
|
||||
*/
|
||||
AccountManager(CollaborationConnection manager) {
|
||||
public AccountManager(CollaborationConnection manager) {
|
||||
sessionManager = manager;
|
||||
subscriptionEventListener = new SubscriptionPacketListener(
|
||||
sessionManager);
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.account;
|
||||
|
||||
import java.net.URI;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
@ -50,6 +50,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 24, 2014 2756 bclement Initial creation
|
||||
* Apr 14, 2014 2903 bclement moved from session subpackage to account
|
||||
*
|
||||
* </pre>
|
||||
*
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.account;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.roster.SubscriptionResponse;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
@ -32,6 +32,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 04, 2014 2785 mpduff Initial creation
|
||||
* Apr 14, 2014 2903 bclement moved from session subpackage to account
|
||||
*
|
||||
* </pre>
|
||||
*
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.account;
|
||||
|
||||
import org.jivesoftware.smack.PacketListener;
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
|
@ -32,6 +32,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent;
|
|||
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.roster.ISubscriptionResponder;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.roster.SubscriptionResponse;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
|
||||
|
@ -49,6 +50,8 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 04, 2014 2785 mpduff Initial creation
|
||||
* Apr 14, 2014 2903 bclement moved from session subpackage to account
|
||||
* Apr 24, 2014 3070 bclement RosterChangeEvent changes, adds back even if blocked
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -117,10 +120,8 @@ public class SubscriptionPacketListener implements PacketListener,
|
|||
* @param fromID
|
||||
*/
|
||||
private void handleSubscribed(UserId fromID) {
|
||||
ContactsManager cm = sessionManager.getContactsManager();
|
||||
RosterEntry entry = cm.getRosterEntry(fromID);
|
||||
IRosterChangeEvent event = new RosterChangeEvent(RosterChangeType.ADD,
|
||||
entry);
|
||||
fromID);
|
||||
sessionManager.postEvent(event);
|
||||
}
|
||||
|
||||
|
@ -130,13 +131,8 @@ public class SubscriptionPacketListener implements PacketListener,
|
|||
* @param fromID
|
||||
*/
|
||||
private void handleUnsubscribed(UserId fromID) {
|
||||
ContactsManager cm = sessionManager.getContactsManager();
|
||||
RosterEntry entry = cm.getRosterEntry(fromID);
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
IRosterChangeEvent event = new RosterChangeEvent(
|
||||
RosterChangeType.DELETE, entry);
|
||||
RosterChangeType.DELETE, fromID);
|
||||
sessionManager.postEvent(event);
|
||||
}
|
||||
|
||||
|
@ -147,28 +143,29 @@ public class SubscriptionPacketListener implements PacketListener,
|
|||
*/
|
||||
private void handleSubResponse(UserId fromId, SubscriptionResponse response) {
|
||||
Presence.Type subscribedType;
|
||||
ContactsManager cm = sessionManager.getContactsManager();
|
||||
boolean addToRoster = false;
|
||||
if (response.isAccepted()) {
|
||||
subscribedType = Presence.Type.subscribed;
|
||||
RosterEntry entry = cm.getRosterEntry(fromId);
|
||||
if (entry == null) {
|
||||
addToRoster = true;
|
||||
}
|
||||
} else {
|
||||
subscribedType = Presence.Type.unsubscribed;
|
||||
}
|
||||
|
||||
Presence presence = new Presence(subscribedType);
|
||||
try {
|
||||
sendPresence(fromId, presence);
|
||||
if (addToRoster) {
|
||||
if (response.addToGroup()) {
|
||||
cm.addToGroup(response.getGroup(), fromId);
|
||||
} else {
|
||||
cm.addToRoster(fromId);
|
||||
if (response.isAccepted()) {
|
||||
/* add them back */
|
||||
ContactsManager cm = sessionManager.getContactsManager();
|
||||
RosterEntry entry = cm.getRosterEntry(fromId);
|
||||
if (entry != null && ContactsManager.isBlocked(entry)) {
|
||||
/* in roster, but blocked */
|
||||
cm.sendContactRequest(fromId);
|
||||
}
|
||||
if (response.addToGroup()) {
|
||||
/*
|
||||
* if contact is not in roster, this will also send them a
|
||||
* contact request, otherwise it just add them to the group
|
||||
*/
|
||||
cm.addToGroup(response.getGroup(), fromId);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (CollaborationException e) {
|
||||
log.error("Unable to send presence", e);
|
|
@ -17,31 +17,26 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.connection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.Roster;
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.RosterListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.filter.PacketTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import org.jivesoftware.smack.packet.XMPPError;
|
||||
import org.jivesoftware.smack.provider.ProviderManager;
|
||||
import org.jivesoftware.smackx.muc.InvitationListener;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubElementType;
|
||||
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||
import org.jivesoftware.smackx.pubsub.provider.SubscriptionProvider;
|
||||
import org.jivesoftware.smackx.pubsub.provider.SubscriptionsProvider;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.net.HostAndPort;
|
||||
|
@ -50,28 +45,25 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.xmpp.PacketConstants;
|
||||
import com.raytheon.uf.common.xmpp.iq.AuthInfo;
|
||||
import com.raytheon.uf.common.xmpp.iq.AuthInfoProvider;
|
||||
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.IAccountManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.ISession;
|
||||
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.invite.SharedDisplayVenueInvite;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite;
|
||||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload;
|
||||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload.PayloadType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayloadProvider;
|
||||
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.ServerDisconnectEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueInvitationEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.account.AccountManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.account.ClientAuthManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueUserEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CreateSessionData;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.PeerToPeerChat;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.SharedDisplaySession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession;
|
||||
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.UserSearch;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
||||
|
||||
/**
|
||||
|
@ -119,6 +111,10 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
|||
* changed session map to a concurrent hash map
|
||||
* Apr 07, 2014 2785 mpduff Changed the order of startup, sets up listeners before actually connecting.
|
||||
* Apr 09, 2014 2785 mpduff Throw error when not connected and the connection should exist.
|
||||
* Apr 14, 2014 2903 bclement moved from session subpackage to connection, removed password from memory,
|
||||
* moved listeners to own classes, reworked connect/register listeners/login order
|
||||
* Apr 15, 2014 2822 bclement added pubsub owner subscriptions provider registration
|
||||
* Apr 23, 2014 2822 bclement added resource name and getCollaborationVersion()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -135,18 +131,31 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
PacketConstants.COLLAB_XMLNS, new SessionPayloadProvider());
|
||||
pm.addIQProvider(PacketConstants.QUERY_ELEMENT_NAME,
|
||||
AuthInfo.AUTH_QUERY_XMLNS, new AuthInfoProvider());
|
||||
/*
|
||||
* smack doesn't support some of the OWNER operations such as getting
|
||||
* all subscriptions on a node. PubSubOperations creates the request
|
||||
* objects for these operations, but the response needs to be parsed.
|
||||
* Here we register the existing smack parsers using the OWNER
|
||||
* namespace.
|
||||
*/
|
||||
pm.addExtensionProvider(
|
||||
PubSubElementType.SUBSCRIPTION.getElementName(),
|
||||
PubSubNamespace.OWNER.getXmlns(), new SubscriptionProvider());
|
||||
pm.addExtensionProvider(
|
||||
PubSubElementType.SUBSCRIPTIONS.getElementName(),
|
||||
PubSubNamespace.OWNER.getXmlns(), new SubscriptionsProvider());
|
||||
}
|
||||
|
||||
private static final String RESOURCE_BASENAME = "CAVE";
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(CollaborationConnection.class);
|
||||
|
||||
private static CollaborationConnection instance = null;
|
||||
private static volatile CollaborationConnection instance = null;
|
||||
|
||||
private static Map<CollaborationConnectionData, CollaborationConnection> instanceMap = new HashMap<CollaborationConnectionData, CollaborationConnection>();
|
||||
private final Map<String, ISession> sessions;
|
||||
|
||||
private Map<String, ISession> sessions;
|
||||
|
||||
private UserId user;
|
||||
private final UserId user;
|
||||
|
||||
private Presence userPresence;
|
||||
|
||||
|
@ -154,7 +163,7 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
|
||||
private IAccountManager accountManager = null;
|
||||
|
||||
private EventBus eventBus;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private ContactsManager contactsMgr;
|
||||
|
||||
|
@ -162,6 +171,8 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
|
||||
private XMPPConnection connection;
|
||||
|
||||
private final ConnectionConfiguration smackConfig;
|
||||
|
||||
private ClientAuthManager authManager;
|
||||
|
||||
private static boolean COMPRESS = true;
|
||||
|
@ -178,59 +189,127 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 createConnection(
|
||||
CollaborationConnectionData userData) throws CollaborationException {
|
||||
synchronized (CollaborationConnection.class) {
|
||||
if (instance == null) {
|
||||
instance = new CollaborationConnection(userData);
|
||||
} else {
|
||||
throw new CollaborationException("Already connected");
|
||||
}
|
||||
}
|
||||
|
||||
return getConnection();
|
||||
}
|
||||
|
||||
private CollaborationConnection(CollaborationConnectionData connectionData)
|
||||
throws CollaborationException {
|
||||
this.connectionData = connectionData;
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this object.
|
||||
*/
|
||||
private void init() throws CollaborationException {
|
||||
eventBus = new EventBus();
|
||||
sessions = new ConcurrentHashMap<String, ISession>();
|
||||
|
||||
HostAndPort hnp = HostAndPort.fromString(connectionData.getServer());
|
||||
ConnectionConfiguration conConfig;
|
||||
if (hnp.hasPort()) {
|
||||
conConfig = new ConnectionConfiguration(hnp.getHostText(),
|
||||
hnp.getPort());
|
||||
} else {
|
||||
conConfig = new ConnectionConfiguration(hnp.getHostText());
|
||||
}
|
||||
|
||||
conConfig.setCompressionEnabled(COMPRESS);
|
||||
|
||||
connection = new XMPPConnection(conConfig);
|
||||
accountManager = new AccountManager(this);
|
||||
|
||||
this.eventBus = new EventBus();
|
||||
this.sessions = new ConcurrentHashMap<String, ISession>();
|
||||
this.smackConfig = createSmackConfiguration(connectionData);
|
||||
/* connects to XMPP server, but doesn't log in */
|
||||
this.connection = createXmppConnection(smackConfig);
|
||||
/* create managers and listeners before login */
|
||||
this.accountManager = new AccountManager(this);
|
||||
this.user = new UserId(connectionData.getUserName(),
|
||||
connection.getServiceName());
|
||||
|
||||
setupInternalConnectionListeners();
|
||||
getPeerToPeerSession();
|
||||
|
||||
instanceMap.put(connectionData, this);
|
||||
if (instance == null) {
|
||||
instance = this;
|
||||
}
|
||||
this.chatInstance = initPeerToPeerSession();
|
||||
this.contactsMgr = new ContactsManager(this, this.getXmppConnection());
|
||||
registerEventHandler(this.contactsMgr);
|
||||
MultiUserChat.addInvitationListener(connection,
|
||||
new SessionInviteListener(this));
|
||||
PeerToPeerCommHelper helper = new PeerToPeerCommHelper(this);
|
||||
this.connection.addPacketListener(helper, new PacketTypeFilter(
|
||||
Message.class));
|
||||
this.connection.addConnectionListener(new XmppConnectionListener(this));
|
||||
/* login called externally */
|
||||
}
|
||||
|
||||
/**
|
||||
* connect to XMPP server and login
|
||||
* Create smack xmpp configuration object from collaboration connection
|
||||
* options
|
||||
*
|
||||
* @param connectionData
|
||||
* @return
|
||||
*/
|
||||
private static ConnectionConfiguration createSmackConfiguration(
|
||||
CollaborationConnectionData connectionData) {
|
||||
ConnectionConfiguration rval;
|
||||
HostAndPort hnp = HostAndPort.fromString(connectionData.getServer());
|
||||
if (hnp.hasPort()) {
|
||||
rval = new ConnectionConfiguration(hnp.getHostText(), hnp.getPort());
|
||||
} else {
|
||||
rval = new ConnectionConfiguration(hnp.getHostText());
|
||||
}
|
||||
|
||||
rval.setCompressionEnabled(COMPRESS);
|
||||
rval.setReconnectionAllowed(false);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create xmpp connection object and connect. This method does not login
|
||||
*
|
||||
* @param config
|
||||
* @return
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
private static XMPPConnection createXmppConnection(
|
||||
ConnectionConfiguration config) throws CollaborationException {
|
||||
XMPPConnection rval = new XMPPConnection(config);
|
||||
try {
|
||||
rval.connect();
|
||||
} catch (XMPPException e) {
|
||||
throw new CollaborationException(
|
||||
"Problem establishing connection to XMPP server", e);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Login to the XMPP server. This needs to be called after the
|
||||
* CollaborationConnection has been created and initialized.
|
||||
*
|
||||
* @param password
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
public void login(String password) throws CollaborationException {
|
||||
loginInternal(connectionData.getUserName(), password);
|
||||
/* auth needs to be logged in to register public key */
|
||||
authManager = new ClientAuthManager(getXmppConnection());
|
||||
}
|
||||
|
||||
/**
|
||||
* login to XMPP server
|
||||
*
|
||||
* @param username
|
||||
* @param password
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
private void connectInternal(String username, String password)
|
||||
private void loginInternal(String username, String password)
|
||||
throws CollaborationException {
|
||||
try {
|
||||
connection.connect();
|
||||
connection.login(username, password);
|
||||
connection.login(username, password, getResourceName());
|
||||
} catch (XMPPException e) {
|
||||
closeInternals();
|
||||
close();
|
||||
// get a nice reason for the user
|
||||
String msg;
|
||||
XMPPError xmppErr = e.getXMPPError();
|
||||
|
@ -252,9 +331,37 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
msg = e.getLocalizedMessage();
|
||||
}
|
||||
throw new CollaborationException("Login failed: " + msg, e);
|
||||
} finally {
|
||||
/* remove password from smack */
|
||||
SmackConfigScrubber.scrubConfig(smackConfig);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get name used for CAVE collaboration XMPP resource
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String getResourceName() {
|
||||
String rval = RESOURCE_BASENAME;
|
||||
String version = getCollaborationVersion();
|
||||
if (version != null) {
|
||||
rval += "-" + version;
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Activator#getBundleVersion()
|
||||
* @return
|
||||
*/
|
||||
public static String getCollaborationVersion() {
|
||||
return Activator.getBundleVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return login data used to create this connection
|
||||
*/
|
||||
public CollaborationConnectionData getConnectionData() {
|
||||
return connectionData;
|
||||
}
|
||||
|
@ -292,18 +399,25 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
|
||||
/**
|
||||
* Is this SessionManager currently connected?
|
||||
* Is this client currently connected to the XMPP server?
|
||||
*
|
||||
* @return Is this SessionManager currently connected?
|
||||
* @return
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return ((connection != null) && (connection.getConnectionID() != null));
|
||||
return connection != null && connection.isConnected();
|
||||
}
|
||||
|
||||
private void closeInternals() {
|
||||
/**
|
||||
* close any open sessions and disconnect from XMPP server
|
||||
*/
|
||||
public void close() {
|
||||
// Close any created sessions.
|
||||
for (Entry<String, ISession> entry : sessions.entrySet()) {
|
||||
entry.getValue().close();
|
||||
}
|
||||
sessions.clear();
|
||||
chatInstance = null;
|
||||
if (connection != null) {
|
||||
|
||||
chatInstance = null;
|
||||
// Get rid of the account and roster managers
|
||||
if (connection.isConnected()) {
|
||||
connection.disconnect();
|
||||
|
@ -311,31 +425,11 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
connection = null;
|
||||
}
|
||||
PeerToPeerCommHelper.reset();
|
||||
instanceMap.remove(connectionData);
|
||||
if (this == instance) {
|
||||
instance = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void close() {
|
||||
if (connection != null) {
|
||||
// Close any created sessions.
|
||||
Collection<ISession> toRemove = sessions.values();
|
||||
sessions.clear();
|
||||
for (ISession session : toRemove) {
|
||||
if ((chatInstance != null) && chatInstance.equals(session)) {
|
||||
chatInstance.close();
|
||||
chatInstance = null;
|
||||
} else {
|
||||
session.close();
|
||||
}
|
||||
synchronized (CollaborationConnection.class) {
|
||||
if (this == instance) {
|
||||
instance = null;
|
||||
}
|
||||
chatInstance = null;
|
||||
}
|
||||
closeInternals();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -345,14 +439,23 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
* @throws CollaborationException
|
||||
*/
|
||||
public ISession getPeerToPeerSession() throws CollaborationException {
|
||||
if (chatInstance == null) {
|
||||
chatInstance = new PeerToPeerChat(eventBus, this);
|
||||
sessions.put(chatInstance.getSessionId(), chatInstance);
|
||||
postEvent(chatInstance);
|
||||
}
|
||||
return chatInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and initialize peer to peer chat session object.
|
||||
*
|
||||
* @return
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
private PeerToPeerChat initPeerToPeerSession()
|
||||
throws CollaborationException {
|
||||
PeerToPeerChat rval = new PeerToPeerChat(eventBus, this);
|
||||
sessions.put(rval.getSessionId(), rval);
|
||||
postEvent(rval);
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create shared display venue object. This does not create the venue on the
|
||||
* server. The session should be unregistered when no longer active using
|
||||
|
@ -450,6 +553,7 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
|
||||
/**
|
||||
* unregister session with connection and notify UI elements
|
||||
*
|
||||
* @param session
|
||||
*/
|
||||
|
@ -458,227 +562,16 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
postEvent(session);
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// Connection listener
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
* Get registered session
|
||||
*
|
||||
* @param sessionId
|
||||
* @return
|
||||
*/
|
||||
private void setupInternalConnectionListeners() {
|
||||
final Roster roster = connection.getRoster();
|
||||
roster.addRosterListener(new RosterListener() {
|
||||
|
||||
@Override
|
||||
public void presenceChanged(Presence presence) {
|
||||
String fromId = presence.getFrom();
|
||||
if (contactsMgr != null) {
|
||||
UserId u = IDConverter.convertFrom(fromId);
|
||||
if (u != null) {
|
||||
RosterEntry entry = contactsMgr.getRosterEntry(u);
|
||||
eventBus.post(entry);
|
||||
IRosterChangeEvent event = new RosterChangeEvent(
|
||||
RosterChangeType.PRESENCE, entry, presence);
|
||||
eventBus.post(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entriesUpdated(Collection<String> addresses) {
|
||||
send(addresses, RosterChangeType.MODIFY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entriesDeleted(Collection<String> addresses) {
|
||||
send(addresses, RosterChangeType.DELETE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entriesAdded(Collection<String> addresses) {
|
||||
send(addresses, RosterChangeType.ADD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send event bus notification for roster
|
||||
*
|
||||
* @param addresses
|
||||
* @param type
|
||||
*/
|
||||
private void send(Collection<String> addresses,
|
||||
RosterChangeType type) {
|
||||
for (String addy : addresses) {
|
||||
RosterEntry entry = roster.getEntry(addy);
|
||||
if (entry != null) {
|
||||
IRosterChangeEvent event = new RosterChangeEvent(type,
|
||||
entry);
|
||||
eventBus.post(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ISession getSession(String sessionId) {
|
||||
return sessions.get(sessionId);
|
||||
}
|
||||
|
||||
private void setupP2PComm() throws CollaborationException {
|
||||
if (isConnected()) {
|
||||
PeerToPeerCommHelper helper = new PeerToPeerCommHelper(this);
|
||||
connection.addPacketListener(helper, new PacketTypeFilter(
|
||||
Message.class));
|
||||
} else {
|
||||
throw new CollaborationException(
|
||||
"The Collaboration XMPP connection has not been established.");
|
||||
}
|
||||
}
|
||||
|
||||
private void setupConnectionListener() throws CollaborationException {
|
||||
if (isConnected()) {
|
||||
connection.addConnectionListener(new ConnectionListener() {
|
||||
|
||||
@Override
|
||||
public void reconnectionSuccessful() {
|
||||
statusHandler
|
||||
.debug("Client successfully reconnected to server");
|
||||
postSystemMessageToVenues("Connection to collaboration server reestablished.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionFailed(Exception e) {
|
||||
String reason = getErrorReason(e);
|
||||
statusHandler.error("Client can't reconnect to server: "
|
||||
+ reason, e);
|
||||
sendDisconnectNotice(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectingIn(int seconds) {
|
||||
statusHandler.debug("Client reconnecting to server in "
|
||||
+ seconds + " seconds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
String reason = getErrorReason(e);
|
||||
statusHandler.error("Server closed on error: " + reason, e);
|
||||
// don't shutdown yet, we might be able to reconnect
|
||||
postSystemMessageToVenues("Not currently connected to collaboration server.");
|
||||
}
|
||||
|
||||
private String getErrorReason(Exception e) {
|
||||
String msg = null;
|
||||
if (e instanceof XMPPException) {
|
||||
StreamError streamError = ((XMPPException) e)
|
||||
.getStreamError();
|
||||
if (streamError != null) {
|
||||
if ("conflict".equalsIgnoreCase(streamError
|
||||
.getCode())) {
|
||||
msg = "User account in use on another client";
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg == null ? e.getLocalizedMessage() : msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
statusHandler.info("Server closed connection");
|
||||
sendDisconnectNotice("Normal termination");
|
||||
}
|
||||
|
||||
private void sendDisconnectNotice(String reason) {
|
||||
ServerDisconnectEvent event = new ServerDisconnectEvent(
|
||||
reason);
|
||||
eventBus.post(event);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new CollaborationException(
|
||||
"The Collaboration XMPP connection has not been established.");
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************
|
||||
// Venue invitation listener management
|
||||
// ***************************
|
||||
|
||||
/**
|
||||
* Set up the invitation listener.
|
||||
*
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
private void setupInternalVenueInvitationListener()
|
||||
throws CollaborationException {
|
||||
if (isConnected()) {
|
||||
MultiUserChat.addInvitationListener(connection,
|
||||
new InvitationListener() {
|
||||
@Override
|
||||
public void invitationReceived(Connection conn,
|
||||
String room, String inviter, String reason,
|
||||
String password, Message message) {
|
||||
// TODO handle password protected rooms
|
||||
VenueId venueId = new VenueId();
|
||||
venueId.setName(Tools.parseName(room));
|
||||
venueId.setHost(Tools.parseHost(room));
|
||||
UserId invitor = IDConverter.convertFrom(inviter);
|
||||
|
||||
if (message != null) {
|
||||
SessionPayload payload = (SessionPayload) message
|
||||
.getExtension(PacketConstants.COLLAB_XMLNS);
|
||||
if (payload != null) {
|
||||
handleCollabInvite(venueId, invitor,
|
||||
payload);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (reason != null
|
||||
&& reason.startsWith(Tools.CMD_PREAMBLE)) {
|
||||
reason = "Shared display invitation from incompatible version of CAVE. "
|
||||
+ "Session will be chat-only if invitation is accepted";
|
||||
}
|
||||
handleChatRoomInvite(venueId, invitor, reason,
|
||||
message);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new CollaborationException(
|
||||
"The Collaboration XMPP connection has not been established.");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleChatRoomInvite(VenueId venueId, UserId invitor,
|
||||
String reason, Message message) {
|
||||
VenueInvite invite = new VenueInvite();
|
||||
if (!StringUtils.isBlank(reason)) {
|
||||
invite.setMessage(reason);
|
||||
} else if (!StringUtils.isBlank(message.getBody())) {
|
||||
invite.setMessage(message.getBody());
|
||||
} else {
|
||||
invite.setMessage("");
|
||||
}
|
||||
invite.setSubject(message.getSubject());
|
||||
IVenueInvitationEvent event = new VenueInvitationEvent(venueId,
|
||||
invitor, invite);
|
||||
eventBus.post(event);
|
||||
}
|
||||
|
||||
private void handleCollabInvite(VenueId venueId, UserId invitor,
|
||||
SessionPayload payload) {
|
||||
Object obj = payload.getData();
|
||||
if (obj == null
|
||||
|| !payload.getPayloadType().equals(PayloadType.Invitation)
|
||||
|| !(obj instanceof VenueInvite)) {
|
||||
statusHandler.warn("Received unsupported invite payload");
|
||||
return;
|
||||
}
|
||||
VenueInvite invite = (VenueInvite) obj;
|
||||
IVenueInvitationEvent event = new VenueInvitationEvent(venueId,
|
||||
invitor, invite);
|
||||
eventBus.post(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event handler with this
|
||||
*
|
||||
|
@ -712,38 +605,10 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
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 createConnection(
|
||||
CollaborationConnectionData userData) throws CollaborationException {
|
||||
if (instance != null) {
|
||||
throw new CollaborationException("Already connected");
|
||||
}
|
||||
|
||||
instance = new CollaborationConnection(userData);
|
||||
|
||||
return getConnection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Smack connection object
|
||||
*/
|
||||
protected XMPPConnection getXmppConnection() {
|
||||
public XMPPConnection getXmppConnection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -776,23 +641,9 @@ public class CollaborationConnection implements IEventPublisher {
|
|||
}
|
||||
|
||||
/**
|
||||
* Connect to the XMPP server. This needs to be called after the
|
||||
* CollaborationConnection has been created and initialized.
|
||||
*
|
||||
* @throws CollaborationException
|
||||
* @return the statusHandler
|
||||
*/
|
||||
public void connect() throws CollaborationException {
|
||||
contactsMgr = new ContactsManager(this, this.getXmppConnection());
|
||||
registerEventHandler(instance.getContactsManager());
|
||||
|
||||
connectInternal(connectionData.getUserName(),
|
||||
connectionData.getPassword());
|
||||
|
||||
authManager = new ClientAuthManager(getXmppConnection());
|
||||
|
||||
// Finish setup
|
||||
setupInternalVenueInvitationListener();
|
||||
setupP2PComm();
|
||||
setupConnectionListener();
|
||||
protected static IUFStatusHandler getStatusHandler() {
|
||||
return statusHandler;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.connection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -36,6 +36,7 @@ import org.jivesoftware.smack.packet.Presence.Mode;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 18, 2012 mschenke Initial creation
|
||||
* Jan 15, 2014 2630 bclement connection data stores status as Mode object
|
||||
* Apr 14, 2014 2903 bclement removed password, moved from session subpackage to connection
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -49,8 +50,6 @@ public class CollaborationConnectionData {
|
|||
|
||||
private String userName;
|
||||
|
||||
private String password;
|
||||
|
||||
private Mode status;
|
||||
|
||||
private String message;
|
||||
|
@ -91,21 +90,6 @@ public class CollaborationConnectionData {
|
|||
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
|
||||
*/
|
||||
|
@ -163,8 +147,6 @@ public class CollaborationConnectionData {
|
|||
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
|
||||
|
@ -196,11 +178,6 @@ public class CollaborationConnectionData {
|
|||
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;
|
|
@ -17,7 +17,7 @@
|
|||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.connection;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
@ -63,6 +63,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Feb 17, 2014 2756 bclement null check for message from field
|
||||
* moved url validation from regex to java utility
|
||||
* Feb 24, 2014 2756 bclement moved xmpp objects to new packages
|
||||
* Apr 14, 2014 2903 bclement moved from session subpackage to connection
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -72,8 +73,8 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
|
||||
public class PeerToPeerCommHelper implements PacketListener {
|
||||
|
||||
private static final transient IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(PeerToPeerCommHelper.class);
|
||||
private static final transient IUFStatusHandler statusHandler = CollaborationConnection
|
||||
.getStatusHandler();
|
||||
|
||||
private static volatile String httpServer;
|
||||
|
||||
|
@ -88,7 +89,7 @@ public class PeerToPeerCommHelper implements PacketListener {
|
|||
return httpServer;
|
||||
}
|
||||
|
||||
private CollaborationConnection manager;
|
||||
private final CollaborationConnection manager;
|
||||
|
||||
/**
|
||||
*
|
|
@ -0,0 +1,149 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 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.connection;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jivesoftware.smack.Connection;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.muc.InvitationListener;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.xmpp.PacketConstants;
|
||||
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.packet.SessionPayload;
|
||||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload.PayloadType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueInvitationEvent;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Handles incoming session invitations and routes to event bus
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2014 2903 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SessionInviteListener implements InvitationListener {
|
||||
|
||||
private static final IUFStatusHandler statusHandler = CollaborationConnection
|
||||
.getStatusHandler();
|
||||
|
||||
private final CollaborationConnection manager;
|
||||
|
||||
/**
|
||||
* @param manager
|
||||
*/
|
||||
public SessionInviteListener(CollaborationConnection manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jivesoftware.smackx.muc.InvitationListener#invitationReceived(org
|
||||
* .jivesoftware.smack.Connection, java.lang.String, java.lang.String,
|
||||
* java.lang.String, java.lang.String,
|
||||
* org.jivesoftware.smack.packet.Message)
|
||||
*/
|
||||
@Override
|
||||
public void invitationReceived(Connection conn, String room,
|
||||
String inviter, String reason, String password, Message message) {
|
||||
// TODO handle password protected rooms
|
||||
VenueId venueId = new VenueId();
|
||||
venueId.setName(Tools.parseName(room));
|
||||
venueId.setHost(Tools.parseHost(room));
|
||||
UserId invitor = IDConverter.convertFrom(inviter);
|
||||
|
||||
SessionPayload payload = null;
|
||||
if (message != null) {
|
||||
payload = (SessionPayload) message
|
||||
.getExtension(PacketConstants.COLLAB_XMLNS);
|
||||
}
|
||||
if (reason != null && reason.startsWith(Tools.CMD_PREAMBLE)) {
|
||||
reason = "Shared display invitation from incompatible version of CAVE. "
|
||||
+ "Session will be chat-only if invitation is accepted";
|
||||
}
|
||||
if (payload != null) {
|
||||
handleCollabInvite(venueId, invitor, payload);
|
||||
} else {
|
||||
handleChatRoomInvite(venueId, invitor, reason, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles acceptance of a text only session invitation
|
||||
*
|
||||
* @param venueId
|
||||
* @param invitor
|
||||
* @param reason
|
||||
* @param message
|
||||
*/
|
||||
private void handleChatRoomInvite(VenueId venueId, UserId invitor,
|
||||
String reason, Message message) {
|
||||
VenueInvite invite = new VenueInvite();
|
||||
if (!StringUtils.isBlank(reason)) {
|
||||
invite.setMessage(reason);
|
||||
} else if (!StringUtils.isBlank(message.getBody())) {
|
||||
invite.setMessage(message.getBody());
|
||||
} else {
|
||||
invite.setMessage("");
|
||||
}
|
||||
invite.setSubject(message.getSubject());
|
||||
IVenueInvitationEvent event = new VenueInvitationEvent(venueId,
|
||||
invitor, invite);
|
||||
manager.postEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles acceptance of a shared display session invitation
|
||||
*
|
||||
* @param venueId
|
||||
* @param invitor
|
||||
* @param payload
|
||||
*/
|
||||
private void handleCollabInvite(VenueId venueId, UserId invitor,
|
||||
SessionPayload payload) {
|
||||
Object obj = payload.getData();
|
||||
if (obj == null
|
||||
|| !payload.getPayloadType().equals(PayloadType.Invitation)
|
||||
|| !(obj instanceof VenueInvite)) {
|
||||
statusHandler.warn("Received unsupported invite payload");
|
||||
return;
|
||||
}
|
||||
VenueInvite invite = (VenueInvite) obj;
|
||||
IVenueInvitationEvent event = new VenueInvitationEvent(venueId,
|
||||
invitor, invite);
|
||||
manager.postEvent(event);
|
||||
}
|
||||
|
||||
}
|
|
@ -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.collaboration.comm.provider.connection;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionConfiguration;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
|
||||
/**
|
||||
* Sanitizes smack configuration object to keep sensitive information out of the
|
||||
* heap
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2014 2903 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class SmackConfigScrubber {
|
||||
|
||||
private static final IUFStatusHandler log = CollaborationConnection
|
||||
.getStatusHandler();
|
||||
|
||||
private static volatile Field passwordField;
|
||||
|
||||
private static final String PASSWORD_FIELD_NAME = "password";
|
||||
|
||||
private SmackConfigScrubber() {
|
||||
}
|
||||
|
||||
/**
|
||||
* remove sensitive information from smack configuration
|
||||
*
|
||||
* @param config
|
||||
*/
|
||||
public static void scrubConfig(ConnectionConfiguration config) {
|
||||
if (passwordField == null) {
|
||||
synchronized (SmackConfigScrubber.class) {
|
||||
if (passwordField == null) {
|
||||
passwordField = createPasswordField();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (passwordField != null) {
|
||||
try {
|
||||
passwordField.set(config, null);
|
||||
} catch (Exception e) {
|
||||
log.debug("Unable to scrub xmpp configuration: "
|
||||
+ e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a field object for the connection configuration class object
|
||||
*
|
||||
* @return null if unable to create
|
||||
*/
|
||||
private static Field createPasswordField() {
|
||||
try {
|
||||
Class<?> c = ConnectionConfiguration.class;
|
||||
Field rval = c.getDeclaredField(PASSWORD_FIELD_NAME);
|
||||
rval.setAccessible(true);
|
||||
return rval;
|
||||
} catch (Exception e) {
|
||||
log.debug("Unable to access xmpp configuration: "
|
||||
+ e.getLocalizedMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.comm.provider.connection;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionListener;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.ServerDisconnectEvent;
|
||||
|
||||
/**
|
||||
* Handles connection events from the XMPP server
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2014 2903 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class XmppConnectionListener implements ConnectionListener {
|
||||
|
||||
private static final IUFStatusHandler statusHandler = CollaborationConnection
|
||||
.getStatusHandler();
|
||||
|
||||
private final CollaborationConnection manager;
|
||||
|
||||
/**
|
||||
* @param manager
|
||||
*/
|
||||
public XmppConnectionListener(CollaborationConnection manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionSuccessful() {
|
||||
/* this will not be called since we don't allow auto reconnect */
|
||||
statusHandler.debug("Client successfully reconnected to server");
|
||||
manager.postSystemMessageToVenues("Connection to collaboration server reestablished.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectionFailed(Exception e) {
|
||||
/* this will not be called since we don't allow auto reconnect */
|
||||
String reason = getErrorReason(e);
|
||||
statusHandler.error("Client can't reconnect to server: " + reason, e);
|
||||
sendDisconnectNotice(reason);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reconnectingIn(int seconds) {
|
||||
/* this will not be called since we don't allow auto reconnect */
|
||||
statusHandler.debug("Client reconnecting to server in " + seconds
|
||||
+ " seconds");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosedOnError(Exception e) {
|
||||
String reason = getErrorReason(e);
|
||||
statusHandler.error("Server closed on error: " + reason, e);
|
||||
sendDisconnectNotice(reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to get the most meaningful message from XMPP exception
|
||||
*
|
||||
* @param e
|
||||
* @return
|
||||
*/
|
||||
private String getErrorReason(Exception e) {
|
||||
String msg = null;
|
||||
if (e instanceof XMPPException) {
|
||||
StreamError streamError = ((XMPPException) e).getStreamError();
|
||||
if (streamError != null) {
|
||||
if ("conflict".equalsIgnoreCase(streamError.getCode())) {
|
||||
msg = "User account in use on another client";
|
||||
}
|
||||
}
|
||||
}
|
||||
return msg == null ? e.getLocalizedMessage() : msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectionClosed() {
|
||||
statusHandler.info("Server closed connection");
|
||||
/* don't send notice for normal termination */
|
||||
}
|
||||
|
||||
/**
|
||||
* Alert event bus listeners of disconnect
|
||||
*
|
||||
* @param reason
|
||||
*/
|
||||
private void sendDisconnectNotice(String reason) {
|
||||
ServerDisconnectEvent event = new ServerDisconnectEvent(reason);
|
||||
manager.postEvent(event);
|
||||
}
|
||||
|
||||
}
|
|
@ -19,11 +19,11 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.event;
|
||||
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
||||
/**
|
||||
* Event posted when a roster entry needs to be updated
|
||||
|
@ -36,6 +36,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2012 jkorman Initial creation
|
||||
* Feb 24, 2014 2632 mpduff Added getPresence, changed getItem to getEntry.
|
||||
* Apr 24, 2014 3070 bclement getEntry() returns UserId
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -47,7 +48,7 @@ public class RosterChangeEvent implements IRosterChangeEvent {
|
|||
|
||||
private final RosterChangeType type;
|
||||
|
||||
private final RosterEntry entry;
|
||||
private final UserId entry;
|
||||
|
||||
/** The presence object */
|
||||
private Presence presence;
|
||||
|
@ -60,7 +61,7 @@ public class RosterChangeEvent implements IRosterChangeEvent {
|
|||
* @param entry
|
||||
* The changed entry.
|
||||
*/
|
||||
public RosterChangeEvent(RosterChangeType type, RosterEntry entry) {
|
||||
public RosterChangeEvent(RosterChangeType type, UserId entry) {
|
||||
this.type = type;
|
||||
this.entry = entry;
|
||||
}
|
||||
|
@ -76,7 +77,7 @@ public class RosterChangeEvent implements IRosterChangeEvent {
|
|||
* @param presence
|
||||
* The presence object
|
||||
*/
|
||||
public RosterChangeEvent(RosterChangeType type, RosterEntry entry,
|
||||
public RosterChangeEvent(RosterChangeType type, UserId entry,
|
||||
Presence presence) {
|
||||
this.type = type;
|
||||
this.entry = entry;
|
||||
|
@ -102,7 +103,7 @@ public class RosterChangeEvent implements IRosterChangeEvent {
|
|||
* @see com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent#getEntry()
|
||||
*/
|
||||
@Override
|
||||
public RosterEntry getEntry() {
|
||||
public UserId getEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ 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.identity.user.IUser;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
|
||||
/**
|
||||
* Base class for chat and collaboration sessions
|
||||
|
|
|
@ -34,6 +34,7 @@ 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.IUser;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.TextMessage;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
||||
/**
|
||||
|
@ -51,6 +52,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Apr 18, 2012 njensen Cleanup
|
||||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Feb 13, 2014 2751 bclement changed IQualifiedID objects to IUser
|
||||
* Apr 11, 2014 2903 bclement made constructor public b/c connection code moved packages
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -66,7 +68,7 @@ public class PeerToPeerChat extends BaseSession implements IPeerToPeer {
|
|||
* @param externalBus
|
||||
* @param manager
|
||||
*/
|
||||
PeerToPeerChat(EventBus externalBus,
|
||||
public PeerToPeerChat(EventBus externalBus,
|
||||
CollaborationConnection manager) throws CollaborationException {
|
||||
super(externalBus, manager);
|
||||
}
|
||||
|
|
|
@ -19,9 +19,18 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.comm.provider.session;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.Packet;
|
||||
import org.jivesoftware.smackx.pubsub.Node;
|
||||
import org.jivesoftware.smackx.pubsub.NodeExtension;
|
||||
import org.jivesoftware.smackx.pubsub.PubSubElementType;
|
||||
import org.jivesoftware.smackx.pubsub.Subscription;
|
||||
import org.jivesoftware.smackx.pubsub.SubscriptionsExtension;
|
||||
import org.jivesoftware.smackx.pubsub.packet.PubSub;
|
||||
import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace;
|
||||
import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
|
||||
|
@ -38,7 +47,8 @@ import com.raytheon.uf.common.xmpp.ext.ChangeAffiliationExtension;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 18, 2014 2751 bclement Initial creation
|
||||
* Feb 18, 2014 2751 bclement Initial creation
|
||||
* Apr 15, 2014 2822 bclement added getAllSubscriptions()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -47,11 +57,14 @@ import com.raytheon.uf.common.xmpp.ext.ChangeAffiliationExtension;
|
|||
*/
|
||||
public class PubSubOperations {
|
||||
|
||||
public static final String PUBSUB_SUBDOMAIN_PREFIX = "pubsub.";
|
||||
|
||||
private PubSubOperations() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Send packet to change affiliation of user on a pubsub topic node
|
||||
* Send packet to change affiliation of user on a pubsub topic node. Calling
|
||||
* client must be owner of node.
|
||||
*
|
||||
* @param conn
|
||||
* @param affiliation
|
||||
|
@ -59,12 +72,56 @@ public class PubSubOperations {
|
|||
*/
|
||||
public static void sendAffiliationPacket(XMPPConnection conn,
|
||||
ChangeAffiliationExtension affiliation) throws XMPPException {
|
||||
PubSub packet = new PubSub();
|
||||
packet.setType(IQ.Type.SET);
|
||||
packet.setTo("pubsub." + conn.getServiceName());
|
||||
packet.setPubSubNamespace(PubSubNamespace.OWNER);
|
||||
packet.addExtension(affiliation);
|
||||
PubSub packet = createOwnerPacket(conn, affiliation, IQ.Type.SET);
|
||||
SyncPacketSend.getReply(conn, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all subscriptions on node. Calling client must be owner of node.
|
||||
*
|
||||
* @param conn
|
||||
* @param n
|
||||
* @return
|
||||
* @throws XMPPException
|
||||
*/
|
||||
public static List<Subscription> getAllSubscriptions(XMPPConnection conn,
|
||||
Node n) throws XMPPException {
|
||||
PubSubElementType type = PubSubElementType.SUBSCRIPTIONS;
|
||||
/*
|
||||
* we need to use the OWNER namespace when we make the request, but we
|
||||
* reuse the provider (parser) for the default namespace for the return.
|
||||
* Use the default namespace to get the extension object from the packet
|
||||
*/
|
||||
String namespace = type.getNamespace().getXmlns();
|
||||
NodeExtension ext = new NodeExtension(type, n.getId());
|
||||
PubSub packet = createOwnerPacket(conn, ext, Type.GET);
|
||||
Packet reply = SyncPacketSend.getReply(conn, packet);
|
||||
SubscriptionsExtension resp = (SubscriptionsExtension) reply
|
||||
.getExtension(type.getElementName(), namespace);
|
||||
if (resp == null){
|
||||
throw new XMPPException(
|
||||
"Subscriptions response missing content for topic: "
|
||||
+ n.getId());
|
||||
}
|
||||
return resp.getSubscriptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create pubsub packet object with owner namespace
|
||||
*
|
||||
* @param conn
|
||||
* @param ext
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
private static PubSub createOwnerPacket(XMPPConnection conn,
|
||||
NodeExtension ext, Type type) {
|
||||
PubSub packet = new PubSub();
|
||||
packet.setType(type);
|
||||
packet.setTo(PUBSUB_SUBDOMAIN_PREFIX + conn.getServiceName());
|
||||
packet.setPubSubNamespace(PubSubNamespace.OWNER);
|
||||
packet.addExtension(ext);
|
||||
return packet;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -63,7 +63,12 @@ import com.raytheon.uf.viz.collaboration.comm.identity.user.SharedDisplayRole;
|
|||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload;
|
||||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload.PayloadType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.account.ClientAuthManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.PeerToPeerCommHelper;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.LeaderChangeEvent;
|
||||
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.VenueParticipant;
|
||||
|
||||
|
@ -92,6 +97,10 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
|||
* Mar 07, 2014 2848 bclement moved pubsub close logic to closePubSub()
|
||||
* ensure that subscription is setup before joining room
|
||||
* Mar 31, 2014 2899 mpduff Improve error messages.
|
||||
* Apr 15, 2014 2822 bclement added check for other participants being subscribed to topic
|
||||
* Apr 21, 2014 2822 bclement removed use of resources in topicSubscribers, added skipCache
|
||||
* Apr 22, 2014 2903 bclement added connection test to closePubSub() method
|
||||
* Apr 23, 2014 2822 bclement added formatInviteAddress()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -113,6 +122,8 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
|
||||
private LeafNode topic;
|
||||
|
||||
private final Set<String> topicSubscribers = new HashSet<String>();
|
||||
|
||||
private XMPPConnection conn;
|
||||
|
||||
private boolean closed = false;
|
||||
|
@ -503,21 +514,24 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
closePubSub();
|
||||
}
|
||||
|
||||
/**
|
||||
* clean up pub sub subscription and objects
|
||||
*/
|
||||
private void closePubSub() {
|
||||
try {
|
||||
if (pubsubMgr == null || topic == null || !topicExists()) {
|
||||
return;
|
||||
}
|
||||
Subscription sub = findSubscription(getAccount());
|
||||
if (sub == null) {
|
||||
return;
|
||||
}
|
||||
topic.unsubscribe(sub.getJid(), sub.getId());
|
||||
topic.removeItemDeleteListener(this);
|
||||
topic.removeItemEventListener(this);
|
||||
if (hasRole(SharedDisplayRole.SESSION_LEADER)) {
|
||||
cleanUpHttpStorage(topic.getId());
|
||||
pubsubMgr.deleteNode(topic.getId());
|
||||
if (conn != null && conn.isConnected() && pubsubMgr != null
|
||||
&& topic != null && topicExists()) {
|
||||
Subscription sub = findSubscription(getAccount());
|
||||
if (sub == null) {
|
||||
return;
|
||||
}
|
||||
topic.unsubscribe(sub.getJid(), sub.getId());
|
||||
topic.removeItemDeleteListener(this);
|
||||
topic.removeItemEventListener(this);
|
||||
if (hasRole(SharedDisplayRole.SESSION_LEADER)) {
|
||||
cleanUpHttpStorage(topic.getId());
|
||||
pubsubMgr.deleteNode(topic.getId());
|
||||
}
|
||||
}
|
||||
topic = null;
|
||||
pubsubMgr = null;
|
||||
|
@ -621,6 +635,41 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
PubSubOperations.sendAffiliationPacket(conn, affiliation);
|
||||
}
|
||||
|
||||
/**
|
||||
* may return false positives if skipCache is set to false, won't return a
|
||||
* false negative
|
||||
*
|
||||
* @param user
|
||||
* @param skipCache
|
||||
* if true, a list of current subscribers is always retrieved
|
||||
* from the server
|
||||
* @return return false if user doesn't have a subscription to the session
|
||||
* topic
|
||||
* @throws XMPPException
|
||||
*/
|
||||
private boolean isSubscribedToTopic(UserId user, boolean skipCache)
|
||||
throws XMPPException {
|
||||
boolean rval;
|
||||
synchronized (topicSubscribers) {
|
||||
rval = topicSubscribers.contains(user.getNormalizedId());
|
||||
if (skipCache || !rval) {
|
||||
topicSubscribers.clear();
|
||||
List<Subscription> subs = PubSubOperations.getAllSubscriptions(
|
||||
conn, topic);
|
||||
for (Subscription sub : subs) {
|
||||
/*
|
||||
* we can't use the resource from the subscription here
|
||||
* because the room user won't always have a resource
|
||||
*/
|
||||
UserId subber = IDConverter.convertFrom(sub.getJid());
|
||||
topicSubscribers.add(subber.getNormalizedId());
|
||||
}
|
||||
rval = topicSubscribers.contains(user.getNormalizedId());
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeLeader(VenueParticipant newLeader)
|
||||
throws CollaborationException {
|
||||
|
@ -634,6 +683,16 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
throw new CollaborationException(
|
||||
"Unable to grant ownership because new leader's actual userid is not known");
|
||||
}
|
||||
/*
|
||||
* leadership transfer must be sync'd between room ownership and topic
|
||||
* ownership. If a user is in the room under multiple handles, we can't
|
||||
* know for sure that this handle is associated with the same client
|
||||
* that understands leadership and is subscribed to the pubsub topic
|
||||
*/
|
||||
if (hasMultipleHandles(actualId)) {
|
||||
throw new CollaborationException(
|
||||
"Unable to grant ownership because new leader is in the room under multiple handles");
|
||||
}
|
||||
|
||||
final String newLeaderId = actualId.getNormalizedId();
|
||||
|
||||
|
@ -642,6 +701,16 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
boolean othersNotified = false;
|
||||
String revokeTarget = null;
|
||||
try {
|
||||
/*
|
||||
* make sure that the new leader is not just in the room, but also
|
||||
* subscribed to the pubsub topic. Skip cache to handle participants
|
||||
* who may have switched clients since that last time we cached
|
||||
*/
|
||||
if (!isSubscribedToTopic(actualId, true)) {
|
||||
throw new CollaborationException(
|
||||
"Unable to grant ownership because new leader is not subscribed to session topic");
|
||||
}
|
||||
|
||||
// was formerly the data provider, so hand off pubsub ownership
|
||||
grantTopicOwnership(newLeaderId);
|
||||
topicOwnershipGranted = true;
|
||||
|
@ -667,6 +736,8 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
// 'member' instead of just down to 'admin'
|
||||
revokeTarget = "room";
|
||||
muc.revokeAdmin(account.getNormalizedId());
|
||||
// clear cache of topic subscribers
|
||||
topicSubscribers.clear();
|
||||
} catch (XMPPException e) {
|
||||
if (!othersNotified) {
|
||||
// transaction, attempt to roll back the ownership changes
|
||||
|
@ -710,4 +781,54 @@ public class SharedDisplaySession extends VenueSession implements
|
|||
return closed;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.collaboration.comm.identity.ISharedDisplaySession
|
||||
* #isSharedDisplayClient
|
||||
* (com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant)
|
||||
*/
|
||||
@Override
|
||||
public boolean isSharedDisplayClient(VenueParticipant participant) {
|
||||
UserId actualId = getVenue().getParticipantUserid(participant);
|
||||
boolean rval = false;
|
||||
if (actualId != null) {
|
||||
try {
|
||||
rval = isSubscribedToTopic(actualId, false);
|
||||
} catch (XMPPException e) {
|
||||
log.error("Error checking if user is a shared display client",
|
||||
e);
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession#
|
||||
* formatInviteAddress
|
||||
* (com.raytheon.uf.viz.collaboration.comm.provider.user.UserId)
|
||||
*/
|
||||
@Override
|
||||
protected String formatInviteAddress(UserId id) {
|
||||
CollaborationConnection manager = getConnection();
|
||||
ContactsManager cm = manager.getContactsManager();
|
||||
String resource = cm.getSharedDisplayEnabledResource(id);
|
||||
/*
|
||||
* resource will be null if we can't find a resource that supports
|
||||
* shared displays for this user
|
||||
*/
|
||||
String rval;
|
||||
if (resource == null) {
|
||||
rval = super.formatInviteAddress(id);
|
||||
} else {
|
||||
UserId newId = new UserId(id.getName(), id.getHost(), resource);
|
||||
rval = newId.getFQName();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload;
|
|||
import com.raytheon.uf.viz.collaboration.comm.packet.SessionPayload.PayloadType;
|
||||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.UserNicknameChangedEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueParticipantEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.VenueUserEvent;
|
||||
|
@ -105,6 +106,11 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
|||
* Mar 07, 2014 2848 bclement added getVenueName() and hasOtherParticipants()
|
||||
* moved muc close logic to closeMuc()
|
||||
* handle is now set in constructor
|
||||
* Apr 11, 2014 2903 bclement made constructor public b/c connection code moved packages
|
||||
* Apr 16, 2014 3020 bclement added check for invited rooms in roomExistsOnServer()
|
||||
* Apr 21, 2014 2822 bclement added hasMultipleHandles()
|
||||
* Apr 22, 2014 2903 bclement added connection test to close method
|
||||
* Apr 23, 2014 2822 bclement added formatInviteAddress()
|
||||
*
|
||||
*
|
||||
* </pre>
|
||||
|
@ -145,9 +151,8 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
* @param container
|
||||
* @param eventBus
|
||||
*/
|
||||
protected VenueSession(EventBus externalBus,
|
||||
CollaborationConnection manager, String venueName, String handle,
|
||||
String sessionId) {
|
||||
public VenueSession(EventBus externalBus, CollaborationConnection manager,
|
||||
String venueName, String handle, String sessionId) {
|
||||
super(externalBus, manager, sessionId);
|
||||
this.venueName = venueName;
|
||||
this.handle = handle;
|
||||
|
@ -158,8 +163,8 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
* @param container
|
||||
* @param eventBus
|
||||
*/
|
||||
protected VenueSession(EventBus externalBus,
|
||||
CollaborationConnection manager, CreateSessionData data) {
|
||||
public VenueSession(EventBus externalBus, CollaborationConnection manager,
|
||||
CreateSessionData data) {
|
||||
super(externalBus, manager);
|
||||
this.venueName = data.getName();
|
||||
this.handle = data.getHandle();
|
||||
|
@ -189,7 +194,10 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
muc.removeParticipantListener(participantListener);
|
||||
participantListener = null;
|
||||
}
|
||||
muc.leave();
|
||||
CollaborationConnection conn = getConnection();
|
||||
if (conn != null && conn.isConnected()) {
|
||||
muc.leave();
|
||||
}
|
||||
muc = null;
|
||||
}
|
||||
|
||||
|
@ -218,7 +226,6 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
SessionPayload payload = new SessionPayload(PayloadType.Invitation,
|
||||
invite);
|
||||
Message msg = new Message();
|
||||
msg.setTo(id.getNormalizedId());
|
||||
UserId user = getAccount();
|
||||
msg.setFrom(user.getNormalizedId());
|
||||
msg.setType(Type.normal);
|
||||
|
@ -229,7 +236,17 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
} else if (!StringUtils.isBlank(invite.getSubject())) {
|
||||
reason = invite.getSubject();
|
||||
}
|
||||
muc.invite(msg, id.getNormalizedId(), reason);
|
||||
muc.invite(msg, formatInviteAddress(id), reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* format invite address for user
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
protected String formatInviteAddress(UserId id) {
|
||||
return id.getNormalizedId();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -431,10 +448,11 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
public static boolean roomExistsOnServer(XMPPConnection conn, String roomId)
|
||||
throws XMPPException {
|
||||
String host = Tools.parseHost(roomId);
|
||||
|
||||
/* check for public rooms */
|
||||
ServiceDiscoveryManager serviceDiscoveryManager = new ServiceDiscoveryManager(
|
||||
conn);
|
||||
DiscoverItems result = serviceDiscoveryManager.discoverItems(host);
|
||||
|
||||
for (Iterator<DiscoverItems.Item> items = result.getItems(); items
|
||||
.hasNext();) {
|
||||
DiscoverItems.Item item = items.next();
|
||||
|
@ -442,6 +460,19 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for private rooms that we have access to */
|
||||
try {
|
||||
MultiUserChat.getRoomInfo(conn, roomId);
|
||||
/* getRoomInfo only returns if the room was found */
|
||||
return true;
|
||||
} catch (XMPPException e) {
|
||||
/*
|
||||
* getRoomInfo throws a 404 if the room does exist or is private and
|
||||
* we don't have access. In either case, we can't say that the room
|
||||
* exists
|
||||
*/
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -923,6 +954,25 @@ public class VenueSession extends BaseSession implements IVenueSession {
|
|||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* the return value is only accurate if the actual userIDs of all
|
||||
* participants can be seen by this client
|
||||
*
|
||||
* @param user
|
||||
* @return true if the user is in the room under multiple handles
|
||||
*/
|
||||
protected boolean hasMultipleHandles(UserId user) {
|
||||
int count = 0;
|
||||
IVenue v = getVenue();
|
||||
for (VenueParticipant p : v.getParticipants()) {
|
||||
UserId other = v.getParticipantUserid(p);
|
||||
if (other != null && user.isSameUser(other)) {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count > 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
@ -0,0 +1,244 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 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.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.RosterListener;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Presence.Type;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.IRosterChangeEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
|
||||
|
||||
/**
|
||||
* Keeps track of contacts and resource information. Responsible for sending out
|
||||
* roster change events.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 22, 2014 2822 bclement Initial creation
|
||||
* Apr 24, 2014 3070 bclement removed roster,
|
||||
* RosterChangedEvent sends UserId not RosterEntry
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ContactsListener implements RosterListener {
|
||||
|
||||
private final ContactsManager manager;
|
||||
|
||||
private final Map<String, List<ResourceInfo>> contactResources = new HashMap<String, List<ResourceInfo>>();
|
||||
|
||||
/**
|
||||
* @param manager
|
||||
* @param roster
|
||||
*/
|
||||
public ContactsListener(ContactsManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jivesoftware.smack.RosterListener#presenceChanged(org.jivesoftware
|
||||
* .smack.packet.Presence)
|
||||
*/
|
||||
@Override
|
||||
public void presenceChanged(Presence presence) {
|
||||
String fromId = presence.getFrom();
|
||||
UserId u = IDConverter.convertFrom(fromId);
|
||||
if (u != null) {
|
||||
synchronized (contactResources) {
|
||||
/* if they are logging out */
|
||||
if (presence.getType() == Type.unavailable) {
|
||||
processLogout(u);
|
||||
} else {
|
||||
processUpdate(u, presence);
|
||||
}
|
||||
}
|
||||
RosterEntry entry = manager.getRosterEntry(u);
|
||||
if (entry != null) {
|
||||
post(entry);
|
||||
}
|
||||
IRosterChangeEvent event = new RosterChangeEvent(
|
||||
RosterChangeType.PRESENCE, u, presence);
|
||||
post(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update contact resources when resource logs out. Must be externally
|
||||
* synchronized
|
||||
*
|
||||
* @param uid
|
||||
*/
|
||||
private void processLogout(UserId uid) {
|
||||
String bareId = uid.getNormalizedId();
|
||||
List<ResourceInfo> resources = contactResources.get(bareId);
|
||||
if (resources != null) {
|
||||
String resource = uid.getResource();
|
||||
Iterator<ResourceInfo> iterator = resources.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ResourceInfo next = iterator.next();
|
||||
if (next.getResourceName().equalsIgnoreCase(resource)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
if (resources.isEmpty()) {
|
||||
contactResources.remove(bareId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update contact resources when resource changes (non-logout). Must be
|
||||
* externally synchronized.
|
||||
*
|
||||
* @param uid
|
||||
* @param presence
|
||||
*/
|
||||
private void processUpdate(UserId uid, Presence presence) {
|
||||
String bareId = uid.getNormalizedId();
|
||||
String resource = uid.getResource();
|
||||
List<ResourceInfo> resources = contactResources.get(bareId);
|
||||
if (resources == null) {
|
||||
/* we don't expect a large number of clients per user */
|
||||
resources = new ArrayList<ResourceInfo>(2);
|
||||
contactResources.put(bareId, resources);
|
||||
}
|
||||
ResourceInfo oldInfo = null;
|
||||
for (ResourceInfo ri : resources) {
|
||||
if (ri.getResourceName().equalsIgnoreCase(resource)) {
|
||||
oldInfo = ri;
|
||||
}
|
||||
}
|
||||
/* update resource */
|
||||
if (oldInfo == null) {
|
||||
oldInfo = new ResourceInfo(resource, presence);
|
||||
resources.add(oldInfo);
|
||||
} else {
|
||||
oldInfo.updateInfo(presence);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jivesoftware.smack.RosterListener#entriesUpdated(java.util.Collection
|
||||
* )
|
||||
*/
|
||||
@Override
|
||||
public void entriesUpdated(Collection<String> addresses) {
|
||||
send(addresses, RosterChangeType.MODIFY);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jivesoftware.smack.RosterListener#entriesDeleted(java.util.Collection
|
||||
* )
|
||||
*/
|
||||
@Override
|
||||
public void entriesDeleted(Collection<String> addresses) {
|
||||
send(addresses, RosterChangeType.DELETE);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* org.jivesoftware.smack.RosterListener#entriesAdded(java.util.Collection)
|
||||
*/
|
||||
@Override
|
||||
public void entriesAdded(Collection<String> addresses) {
|
||||
send(addresses, RosterChangeType.ADD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send event bus notification for roster
|
||||
*
|
||||
* @param addresses
|
||||
* @param type
|
||||
*/
|
||||
private void send(Collection<String> addresses, RosterChangeType type) {
|
||||
for (String addy : addresses) {
|
||||
UserId entry = IDConverter.convertFrom(addy);
|
||||
/*
|
||||
* RosterChangeEvents can't use RosterEntry objects because DELETE
|
||||
* events happen after the entry is removed from the server roster
|
||||
*/
|
||||
IRosterChangeEvent event = new RosterChangeEvent(type, entry);
|
||||
post(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post event to collaboration event bus
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
private void post(Object event) {
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
connection.postEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name of resource that supports shared displays for user
|
||||
*
|
||||
* @param user
|
||||
* @return null if no resource found for user that supports shared displays
|
||||
*/
|
||||
public String getSharedDisplayEnabledResource(UserId user) {
|
||||
String rval = null;
|
||||
synchronized (contactResources) {
|
||||
List<ResourceInfo> list = contactResources.get(user
|
||||
.getNormalizedId());
|
||||
if (list != null) {
|
||||
for (ResourceInfo ri : list) {
|
||||
if (ri.supportsSharedDisplays()) {
|
||||
rval = ri.getResourceName();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,8 +47,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority;
|
|||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.common.util.collections.UpdatingSet;
|
||||
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.provider.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
|
||||
/**
|
||||
* Manage contacts from local groups and roster on server
|
||||
|
@ -71,6 +72,13 @@ import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConn
|
|||
* Jan 30, 2014 2698 bclement removed unneeded nickname changed event
|
||||
* Jan 31, 2014 2700 bclement added addToRoster, fixed add to group when in roster, but blocked
|
||||
* Feb 3, 2014 2699 bclement fixed assumption that username search was exact
|
||||
* Apr 11, 2014 2903 bclement moved roster listener from collaboration connection to here
|
||||
* Apr 16, 2014 2981 bclement fixed NPE when cached shared group deleted on server
|
||||
* Apr 23, 2014 2822 bclement moved roster listener to ContactsListener,
|
||||
* added getSharedDisplayEnabledResource()
|
||||
* Apr 24, 2014 3070 bclement added checks for empty groups, added isContact(),
|
||||
* added sendContactRequest()
|
||||
* fixed contact request logic in addToGroup()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -83,13 +91,15 @@ public class ContactsManager {
|
|||
.getHandler(ContactsManager.class);
|
||||
|
||||
private final CollaborationConnection connection;
|
||||
|
||||
|
||||
private final XMPPConnection xmpp;
|
||||
|
||||
private final UserSearch search;
|
||||
|
||||
private Map<String, String> localAliases;
|
||||
|
||||
|
||||
private final ContactsListener contactsListener;
|
||||
|
||||
/**
|
||||
* Cached view of shared groups list on openfire. Will only reach out to
|
||||
* server if it hasn't updated in an hour. This will disable itself if there
|
||||
|
@ -127,8 +137,11 @@ public class ContactsManager {
|
|||
this.search = connection.createSearch();
|
||||
localAliases = UserIdWrapper.readAliasMap();
|
||||
this.xmpp = xmpp;
|
||||
Roster roster = xmpp.getRoster();
|
||||
this.contactsListener = new ContactsListener(this);
|
||||
roster.addRosterListener(this.contactsListener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get groups that are managed by server. These are not modifiable from the
|
||||
* client.
|
||||
|
@ -141,7 +154,13 @@ public class ContactsManager {
|
|||
Roster roster = getRoster();
|
||||
for (String group : groups) {
|
||||
RosterGroup rg = roster.getGroup(group);
|
||||
rval.add(new SharedGroup(rg));
|
||||
/*
|
||||
* group will be null if it has been removed from server after
|
||||
* cached in shared groups.
|
||||
*/
|
||||
if (rg != null && !rg.getEntries().isEmpty()) {
|
||||
rval.add(new SharedGroup(rg));
|
||||
}
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
@ -161,7 +180,8 @@ public class ContactsManager {
|
|||
} else {
|
||||
rval = new ArrayList<RosterGroup>(groups.size());
|
||||
for (RosterGroup group : groups) {
|
||||
if (!shared.contains(group.getName())) {
|
||||
if (!shared.contains(group.getName())
|
||||
&& !group.getEntries().isEmpty()) {
|
||||
rval.add(group);
|
||||
}
|
||||
}
|
||||
|
@ -182,24 +202,14 @@ public class ContactsManager {
|
|||
if (group == null) {
|
||||
group = createGroup(groupName);
|
||||
}
|
||||
String id = user.getNormalizedId();
|
||||
RosterEntry entry = group.getEntry(id);
|
||||
if (entry != null) {
|
||||
if (isBlocked(entry)) {
|
||||
// entry is in roster, but we aren't subscribed. Request a
|
||||
// subscription.
|
||||
try {
|
||||
connection.getAccountManager().sendPresence(user,
|
||||
new Presence(Type.subscribe));
|
||||
} catch (CollaborationException e) {
|
||||
statusHandler.error("Problem subscribing to user", e);
|
||||
}
|
||||
} else {
|
||||
statusHandler
|
||||
.debug("Attempted to add user to group it was already in: "
|
||||
+ id + " in " + groupName);
|
||||
RosterEntry entry = getRosterEntry(user);
|
||||
if (entry != null && isBlocked(entry)) {
|
||||
/* entry is in roster, but we are blocked */
|
||||
try {
|
||||
sendContactRequest(user);
|
||||
} catch (CollaborationException e) {
|
||||
statusHandler.error("Problem subscribing to user", e);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
addToGroup(group, user);
|
||||
|
@ -208,8 +218,8 @@ public class ContactsManager {
|
|||
}
|
||||
} catch (XMPPException e) {
|
||||
String msg = getGroupModInfo(e);
|
||||
statusHandler.error("Problem adding user to group: " + id + " to "
|
||||
+ group.getName() + ". " + msg, e);
|
||||
statusHandler.error("Problem adding user to group: " + user
|
||||
+ " to " + group.getName() + ". " + msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,19 +282,20 @@ public class ContactsManager {
|
|||
*/
|
||||
public void deleteFromGroup(String groupName, UserId user) {
|
||||
RosterEntry entry = getRosterEntry(user);
|
||||
if ( entry == null){
|
||||
statusHandler.warn("Attempted to alter group for non-contact: " + user);
|
||||
if (entry == null) {
|
||||
statusHandler.warn("Attempted to alter group for non-contact: "
|
||||
+ user);
|
||||
return;
|
||||
}
|
||||
RosterGroup group = getRoster().getGroup(groupName);
|
||||
if ( group != null){
|
||||
if (group != null) {
|
||||
deleteFromGroup(group, entry);
|
||||
} else {
|
||||
statusHandler.warn("Attempted to modify non-existent group: "
|
||||
+ groupName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove entry from group.
|
||||
*
|
||||
|
@ -299,12 +310,13 @@ public class ContactsManager {
|
|||
}
|
||||
} catch (XMPPException e) {
|
||||
String msg = getGroupModInfo(e);
|
||||
statusHandler.error("Problem removing entry from group: "
|
||||
+ IDConverter.convertFrom(entry) + " from "
|
||||
statusHandler.error(
|
||||
"Problem removing entry from group: "
|
||||
+ IDConverter.convertFrom(entry) + " from "
|
||||
+ group.getName() + ". " + msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to get more information about group modification error. Returns
|
||||
* an empty string if no extra information is found.
|
||||
|
@ -350,8 +362,9 @@ public class ContactsManager {
|
|||
public RosterGroup createGroup(String groupName) {
|
||||
Roster roster = getRoster();
|
||||
RosterGroup rval = roster.getGroup(groupName);
|
||||
if ( rval != null){
|
||||
statusHandler.debug("Attempted to create existing group: " + groupName);
|
||||
if (rval != null) {
|
||||
statusHandler.debug("Attempted to create existing group: "
|
||||
+ groupName);
|
||||
return rval;
|
||||
}
|
||||
rval = roster.createGroup(groupName);
|
||||
|
@ -369,7 +382,7 @@ public class ContactsManager {
|
|||
public void deleteGroup(String groupName) {
|
||||
Roster roster = getRoster();
|
||||
RosterGroup group = roster.getGroup(groupName);
|
||||
if ( group == null){
|
||||
if (group == null) {
|
||||
statusHandler.warn("Attempted to delete non-existent group: "
|
||||
+ groupName);
|
||||
return;
|
||||
|
@ -649,6 +662,7 @@ public class ContactsManager {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
* @return true if we are blocked from seeing updates from user in entry
|
||||
*/
|
||||
|
@ -679,6 +693,51 @@ public class ContactsManager {
|
|||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entry
|
||||
* @return true if we can see updates from user in entry
|
||||
*/
|
||||
public static boolean isContact(RosterEntry entry) {
|
||||
ItemType type = entry.getType();
|
||||
return type != null
|
||||
&& (type.equals(ItemType.both) || type.equals(ItemType.to));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #isContact(RosterEntry)
|
||||
* @param id
|
||||
* @return true if we can see updates from user
|
||||
*/
|
||||
public boolean isContact(UserId id) {
|
||||
RosterEntry entry = getRosterEntry(id);
|
||||
boolean rval = false;
|
||||
if (entry != null) {
|
||||
rval = isContact(entry);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ContactsListener#getSharedDisplayEnabledResource(UserId)
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
public String getSharedDisplayEnabledResource(UserId user) {
|
||||
return contactsListener.getSharedDisplayEnabledResource(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a contact request to user
|
||||
*
|
||||
* @param user
|
||||
* @throws CollaborationException
|
||||
*/
|
||||
public void sendContactRequest(UserId user) throws CollaborationException {
|
||||
IAccountManager manager = connection.getAccountManager();
|
||||
manager.sendPresence(user, new Presence(Type.subscribe));
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener interface for group update events
|
||||
*/
|
||||
|
|
|
@ -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.provider.user;
|
||||
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Presence.Mode;
|
||||
import org.jivesoftware.smack.packet.Presence.Type;
|
||||
|
||||
/**
|
||||
* Information for an XMPP resource (client ie pidgin)
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 22, 2014 2822 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ResourceInfo {
|
||||
|
||||
public static final String VERSION_KEY = "urn:uf:viz:collaboration:version";
|
||||
|
||||
private final String resourceName;
|
||||
|
||||
private String collaborationVersion;
|
||||
|
||||
private Type lastType;
|
||||
|
||||
private Mode lastMode;
|
||||
|
||||
/**
|
||||
* @param resourceName
|
||||
* @param presence
|
||||
*/
|
||||
public ResourceInfo(String resourceName, Presence presence) {
|
||||
this.resourceName = resourceName;
|
||||
updateInfo(presence);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update resource information from presence
|
||||
*
|
||||
* @param presence
|
||||
*/
|
||||
public void updateInfo(Presence presence) {
|
||||
Object version = presence.getProperty(VERSION_KEY);
|
||||
if (version != null) {
|
||||
this.collaborationVersion = version.toString();
|
||||
}
|
||||
this.lastType = presence.getType();
|
||||
this.lastMode = presence.getMode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this resource supports shared displays
|
||||
*/
|
||||
public boolean supportsSharedDisplays() {
|
||||
return this.collaborationVersion != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the resourceName
|
||||
*/
|
||||
public String getResourceName() {
|
||||
return resourceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the collaborationVersion
|
||||
*/
|
||||
public String getCollaborationVersion() {
|
||||
return collaborationVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param collaborationVersion
|
||||
* the collaborationVersion to set
|
||||
*/
|
||||
public void setCollaborationVersion(String collaborationVersion) {
|
||||
this.collaborationVersion = collaborationVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastType
|
||||
*/
|
||||
public Type getLastType() {
|
||||
return lastType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastType
|
||||
* the lastType to set
|
||||
*/
|
||||
public void setLastType(Type lastType) {
|
||||
this.lastType = lastType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lastMode
|
||||
*/
|
||||
public Mode getLastMode() {
|
||||
return lastMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lastMode
|
||||
* the lastMode to set
|
||||
*/
|
||||
public void setLastMode(Mode lastMode) {
|
||||
this.lastMode = lastMode;
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,6 @@ package com.raytheon.uf.viz.collaboration.comm.provider.user;
|
|||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.apache.commons.lang.builder.HashCodeBuilder;
|
||||
|
||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||
|
@ -40,6 +39,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 29, 2014 bclement Initial creation
|
||||
* Feb 13, 2014 2751 bclement no longer is a subclass of UserId
|
||||
* Apr 22, 2014 3056 bclement made equals case insensitive
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -131,12 +131,38 @@ public class VenueParticipant implements IUser {
|
|||
if (!(obj instanceof VenueParticipant)) {
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
* the xmpp server lower cases room names so we may get them back as
|
||||
* lower case when we have them locally as upper/mixed case. Treat case
|
||||
* insensitive.
|
||||
*/
|
||||
VenueParticipant other = (VenueParticipant) obj;
|
||||
EqualsBuilder builder = new EqualsBuilder();
|
||||
builder.append(handle, other.handle);
|
||||
builder.append(host, other.host);
|
||||
builder.append(room, other.room);
|
||||
return builder.isEquals();
|
||||
if (!stringFieldEquals(this.handle, other.handle)){
|
||||
return false;
|
||||
}
|
||||
if (!stringFieldEquals(this.room, other.room)) {
|
||||
return false;
|
||||
}
|
||||
if (!stringFieldEquals(this.host, other.host)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param field
|
||||
* @param other
|
||||
* @return true if both arguments are null or arguments are equal ignoring
|
||||
* case
|
||||
*/
|
||||
private boolean stringFieldEquals(String field, String other) {
|
||||
boolean rval;
|
||||
if (field == null) {
|
||||
rval = other == null;
|
||||
} else {
|
||||
rval = field.equalsIgnoreCase(other);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 3, 2012 mnash Initial creation
|
||||
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
|
||||
* May 05, 2014 3076 bclement added DISPOSE_ALL
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -48,7 +49,7 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
public class CollaborationDrawingEvent {
|
||||
|
||||
public static enum CollaborationEventType {
|
||||
DRAW, ERASE, REDO, UNDO, CLEAR, LOCK_USERS, UNLOCK_USERS, CLEAR_ALL, NEW_USER_ARRIVED;
|
||||
DRAW, ERASE, REDO, UNDO, CLEAR, CLEAR_ALL, LOCK_USERS, UNLOCK_USERS, DISPOSE_ALL, NEW_USER_ARRIVED;
|
||||
}
|
||||
|
||||
@DynamicSerializeElement
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.display.rsc.telestrator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -64,6 +67,8 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
* Jan 30, 2014 2698 bclement changed UserId to VenueParticipant
|
||||
* Feb 13, 2014 2751 bclement VenueParticipant refactor
|
||||
* Mar 18, 2014 2895 njensen Fix concurrent mod exception on dispose
|
||||
* May 05, 2014 3076 bclement old CLEAR_ALL is now DISPOSE_ALL,
|
||||
* added clearLayers() and getAllDrawingLayers()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -129,7 +134,7 @@ public class CollaborationDrawingResource extends
|
|||
CollaborationDrawingEvent event = new CollaborationDrawingEvent(
|
||||
resourceData.getDisplayId());
|
||||
event.setUserName(myUser);
|
||||
event.setType(CollaborationEventType.CLEAR_ALL);
|
||||
event.setType(CollaborationEventType.DISPOSE_ALL);
|
||||
sendEvent(event);
|
||||
}
|
||||
|
||||
|
@ -205,6 +210,18 @@ public class CollaborationDrawingResource extends
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all drawing layers. Does not generate any collaboration events.
|
||||
* This is not "undoable".
|
||||
*/
|
||||
private void clearLayers() {
|
||||
synchronized (layerMap) {
|
||||
for (DrawingToolLayer layer : layerMap.values()) {
|
||||
layer.clearAllDrawingData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the myUser
|
||||
*/
|
||||
|
@ -249,6 +266,23 @@ public class CollaborationDrawingResource extends
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of drawing layers for resource
|
||||
*
|
||||
* @return empty collection if there are no layers
|
||||
*/
|
||||
public Collection<DrawingToolLayer> getAllDrawingLayers() {
|
||||
Collection<DrawingToolLayer> rval;
|
||||
if (layerMap != null) {
|
||||
synchronized (layerMap) {
|
||||
rval = new ArrayList<DrawingToolLayer>(layerMap.values());
|
||||
}
|
||||
} else {
|
||||
rval = Collections.emptyList();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -377,9 +411,12 @@ public class CollaborationDrawingResource extends
|
|||
case UNDO:
|
||||
layer.undo();
|
||||
break;
|
||||
case CLEAR_ALL:
|
||||
case DISPOSE_ALL:
|
||||
disposeLayers();
|
||||
break;
|
||||
case CLEAR_ALL:
|
||||
clearLayers();
|
||||
break;
|
||||
case NEW_USER_ARRIVED:
|
||||
CollaborationDrawingToolLayer myLayer = (CollaborationDrawingToolLayer) getDrawingLayerFor(getMyUser());
|
||||
InitialCollaborationData dataBundle = new InitialCollaborationData(
|
||||
|
|
|
@ -54,8 +54,8 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
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.ClientAuthManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.PeerToPeerCommHelper;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.account.ClientAuthManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.PeerToPeerCommHelper;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
||||
import com.raytheon.uf.viz.remote.graphics.Dispatcher;
|
||||
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
|
||||
|
|
BIN
cave/com.raytheon.uf.viz.collaboration.ui/icons/clear_all.gif
Normal file
BIN
cave/com.raytheon.uf.viz.collaboration.ui/icons/clear_all.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 223 B |
BIN
cave/com.raytheon.uf.viz.collaboration.ui/icons/pending.gif
Normal file
BIN
cave/com.raytheon.uf.viz.collaboration.ui/icons/pending.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 B |
|
@ -35,7 +35,7 @@ import org.jivesoftware.smack.packet.RosterPacket.ItemType;
|
|||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformation;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
||||
/**
|
||||
|
@ -52,6 +52,7 @@ import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
|||
* Feb 13, 2014 2751 bclement made generic for IUsers
|
||||
* Feb 13, 2014 2751 njensen Extracted getImageName() to allow overrides
|
||||
* Feb 17, 2014 2751 bclement moved block image logic to roster specific code
|
||||
* Apr 24, 2014 3070 bclement added pending contact icon
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -103,6 +104,14 @@ public abstract class AbstractUserLabelProvider<T extends IUser> extends
|
|||
return null;
|
||||
}
|
||||
String key = getImageName(user);
|
||||
if (element instanceof RosterEntry) {
|
||||
RosterEntry entry = (RosterEntry) element;
|
||||
ItemStatus status = entry.getStatus();
|
||||
if (status != null) {
|
||||
/* status always indicates pending */
|
||||
key = "pending";
|
||||
}
|
||||
}
|
||||
|
||||
if (imageMap.get(key) == null && !key.equals("")) {
|
||||
imageMap.put(key, CollaborationUtils.getNodeImage(key));
|
||||
|
@ -144,7 +153,8 @@ public abstract class AbstractUserLabelProvider<T extends IUser> extends
|
|||
}
|
||||
ItemStatus status = entry.getStatus();
|
||||
if (status != null) {
|
||||
text.append(status).append(" pending\n");
|
||||
/* status always indicates pending */
|
||||
text.append("Contact request pending\n");
|
||||
}
|
||||
}
|
||||
// delete trailing newline
|
||||
|
|
|
@ -42,6 +42,7 @@ import com.raytheon.uf.viz.core.localization.HierarchicalPreferenceStore;
|
|||
* Mar 1, 2012 rferrel Initial creation
|
||||
* Feb 19, 2014 2631 mpduff Changed to use the HierarchicalPreferenceStore.
|
||||
* Feb 20, 2014 2631 mpduff Need to set defaults here since we changed to use the HierarchicalPreferenceStore
|
||||
* Apr 24, 2014 3070 bclement added default groupname to preference defaults
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -126,6 +127,8 @@ public class Activator extends AbstractUIPlugin {
|
|||
prefs.setDefault(CollabPrefConstants.DEFAULT_HANDLE,
|
||||
CollabPrefConstants.HandleOption.USERNAME.name());
|
||||
prefs.setDefault(CollabPrefConstants.CUSTOM_HANDLE, "");
|
||||
prefs.setDefault(CollabPrefConstants.DEFAULT_GROUPNAME_PREF,
|
||||
"Contacts");
|
||||
}
|
||||
return prefs;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ 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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ 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.PartInitException;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
import org.eclipse.ui.internal.WorkbenchMessages;
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
|
@ -85,9 +86,8 @@ import com.google.common.eventbus.Subscribe;
|
|||
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.identity.event.RosterChangeType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.ServerDisconnectEvent;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
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;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager.GroupListener;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.IDConverter;
|
||||
|
@ -119,10 +119,12 @@ 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.notifier.NotifierTools;
|
||||
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
|
||||
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;
|
||||
import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
||||
|
||||
/**
|
||||
* This class is the main view to display the user's information and allow the
|
||||
|
@ -149,6 +151,8 @@ import com.raytheon.viz.ui.views.CaveFloatingView;
|
|||
* Mar 05, 2014 2837 bclement separate rename action for groups, added more icons
|
||||
* Mar 05, 2014 2798 mpduff Add getter for displayFeedAction.
|
||||
* Mar 12, 2014 2632 mpduff Force group deletes from UI if last user is removed.
|
||||
* Apr 11, 2014 2903 bclement login action changes, removed server disconnect listener,
|
||||
* added static utility method to show view
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -227,12 +231,11 @@ public class CollaborationGroupView extends CaveFloatingView implements
|
|||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
if (connection == null) {
|
||||
new LoginAction().run();
|
||||
connection = CollaborationConnection.getConnection();
|
||||
if (connection == null) {
|
||||
if (!new LoginAction().login()) {
|
||||
// user cancelled login
|
||||
return;
|
||||
}
|
||||
connection = CollaborationConnection.getConnection();
|
||||
}
|
||||
|
||||
createFilterText(parent);
|
||||
|
@ -871,7 +874,7 @@ public class CollaborationGroupView extends CaveFloatingView implements
|
|||
.getActivePage().getViewReferences()) {
|
||||
IViewPart viewPart = ref.getView(false);
|
||||
if (viewPart instanceof AbstractSessionView) {
|
||||
((AbstractSessionView) viewPart).setAlertWords(Arrays
|
||||
((AbstractSessionView<?>) viewPart).setAlertWords(Arrays
|
||||
.asList(words.getAlertWords()));
|
||||
}
|
||||
}
|
||||
|
@ -954,24 +957,32 @@ public class CollaborationGroupView extends CaveFloatingView implements
|
|||
refreshUsersTreeViewerAsync(group);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void serverDisconnected(final ServerDisconnectEvent e) {
|
||||
if (logOut == null) {
|
||||
// we aren't logged in
|
||||
return;
|
||||
}
|
||||
VizApp.runAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
logOut.closeCollaboration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the displayFeedAction
|
||||
*/
|
||||
public DisplayFeedAction getDisplayFeedAction() {
|
||||
return displayFeedAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CaveWorkbenchPageManager#showView(String)
|
||||
*
|
||||
* @param initFeedView
|
||||
* true if feed view should be initialized like this is the first
|
||||
* time the view has been opened
|
||||
* @throws PartInitException
|
||||
*/
|
||||
public static void showView(boolean initFeedView) throws PartInitException {
|
||||
CollaborationGroupView view = (CollaborationGroupView) CaveWorkbenchPageManager
|
||||
.getActiveInstance().showView(ID);
|
||||
if (initFeedView) {
|
||||
// if autojoin is selected (to join the default room)
|
||||
if (Activator.getDefault().getPreferenceStore()
|
||||
.getBoolean(CollabPrefConstants.AUTO_JOIN)) {
|
||||
DisplayFeedAction action = view.getDisplayFeedAction();
|
||||
action.setChecked(true);
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.ui;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
|
@ -40,7 +43,7 @@ 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.user.IUser;
|
||||
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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.ui.actions.PeerToPeerChatAction;
|
||||
import com.raytheon.uf.viz.collaboration.ui.jobs.AwayTimeOut;
|
||||
|
@ -70,6 +73,8 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
|||
* Feb 13, 2014 2751 bclement messages return IUser instead of IQualifiedID
|
||||
* Mar 06, 2014 2848 bclement moved SharedDisplaySessionMgr.joinSession call to InviteDialog
|
||||
* Apr 08, 2014 2785 mpduff removed preference listener
|
||||
* Apr 11, 2014 2903 bclement added disconnect handler
|
||||
* Apr 24, 2014 2955 bclement ignore duplicate session invites
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -88,6 +93,10 @@ public class ConnectionSubscriber {
|
|||
|
||||
private final AwayTimeOut awayTimeOut = new AwayTimeOut();
|
||||
|
||||
private final DisconnectHandler disconnect = new DisconnectHandler();
|
||||
|
||||
private final Set<String> pendingInviteDialogs = new HashSet<String>();
|
||||
|
||||
private ConnectionSubscriber() {
|
||||
}
|
||||
|
||||
|
@ -124,6 +133,7 @@ public class ConnectionSubscriber {
|
|||
new SubscriptionResponderImpl(connection));
|
||||
// Register handlers and events for the new sessionManager.
|
||||
connection.registerEventHandler(this);
|
||||
connection.registerEventHandler(disconnect);
|
||||
try {
|
||||
ISession p2pSession = connection.getPeerToPeerSession();
|
||||
p2pSession.registerEventHandler(this);
|
||||
|
@ -159,11 +169,14 @@ public class ConnectionSubscriber {
|
|||
awayTimeOut.cancel();
|
||||
try {
|
||||
ISession p2pSession = connection.getPeerToPeerSession();
|
||||
p2pSession.unregisterEventHandler(this);
|
||||
if (p2pSession != null) {
|
||||
p2pSession.unregisterEventHandler(this);
|
||||
}
|
||||
} catch (CollaborationException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Error unregistering peer to peer handler", e);
|
||||
}
|
||||
connection.unregisterEventHandler(disconnect);
|
||||
connection.unregisterEventHandler(this);
|
||||
}
|
||||
PlatformUI.getWorkbench().removeWorkbenchListener(wbListener);
|
||||
|
@ -171,16 +184,53 @@ public class ConnectionSubscriber {
|
|||
|
||||
@Subscribe
|
||||
public void handleInvitationEvent(final IVenueInvitationEvent event) {
|
||||
final String roomId = event.getRoomId().getFQName();
|
||||
|
||||
VizApp.runAsync(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Shell shell = new Shell(Display.getCurrent());
|
||||
InviteDialog inviteBox = new InviteDialog(shell, event);
|
||||
if (!(Boolean) inviteBox.open()) {
|
||||
return;
|
||||
if (!invitePending(roomId)) {
|
||||
try {
|
||||
Shell shell = new Shell(Display.getCurrent());
|
||||
InviteDialog inviteBox = new InviteDialog(shell, event);
|
||||
if ((Boolean) inviteBox.open()) {
|
||||
/* user accepted invite */
|
||||
openSession(inviteBox);
|
||||
}
|
||||
} finally {
|
||||
synchronized (pendingInviteDialogs) {
|
||||
pendingInviteDialogs.remove(roomId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
statusHandler.debug("Ignoring duplicate session invite: "
|
||||
+ roomId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param roomId
|
||||
* @return true if there is already an invitation pending for this
|
||||
* room
|
||||
*/
|
||||
private boolean invitePending(String roomId) {
|
||||
synchronized (pendingInviteDialogs) {
|
||||
boolean pending = pendingInviteDialogs.contains(roomId);
|
||||
if (!pending) {
|
||||
/* immediately set to pending to ignore dup invites */
|
||||
pendingInviteDialogs.add(roomId);
|
||||
}
|
||||
return pending;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open session view after invite has been accepted
|
||||
*
|
||||
* @param inviteBox
|
||||
*/
|
||||
private void openSession(InviteDialog inviteBox) {
|
||||
try {
|
||||
IVenueSession session = inviteBox.getSession();
|
||||
if (inviteBox.isSharedDisplay()) {
|
||||
|
|
|
@ -25,15 +25,16 @@ 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.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Layout;
|
||||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||
|
||||
/**
|
||||
|
@ -48,6 +49,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 27, 2012 bsteffen Initial creation
|
||||
* Jan 24, 2014 2701 bclement removed local groups
|
||||
* Apr 23, 2014 3040 lvenable Cleaned up dialog code/layout. Added check for group name.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -56,72 +58,122 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
*/
|
||||
public class CreateGroupDialog extends CaveSWTDialog {
|
||||
|
||||
/** Name text field. */
|
||||
private Text nameText;
|
||||
|
||||
/** New group name. */
|
||||
private String newGroup = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param parentShell
|
||||
* Parent shell.
|
||||
*/
|
||||
public CreateGroupDialog(Shell parentShell) {
|
||||
super(parentShell, SWT.DIALOG_TRIM);
|
||||
setText("Create Group");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Layout constructShellLayout() {
|
||||
GridLayout mainLayout = new GridLayout(1, false);
|
||||
return mainLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object constructShellLayoutData() {
|
||||
return new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
}
|
||||
|
||||
@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);
|
||||
entryComp.setLayout(new GridLayout(2, false));
|
||||
entryComp
|
||||
.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
|
||||
|
||||
new Label(entryComp, SWT.NONE).setText("Group Name: ");
|
||||
nameText = new Text(entryComp, SWT.BORDER);
|
||||
nameText.setLayoutData(new RowData(100, SWT.DEFAULT));
|
||||
nameText.setLayoutData(new GridData(150, SWT.DEFAULT));
|
||||
nameText.addKeyListener(new KeyAdapter() {
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
if (e.keyCode == SWT.CR || e.keyCode == SWT.KEYPAD_CR) {
|
||||
finish();
|
||||
handleOkAction();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* Action buttons
|
||||
*/
|
||||
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);
|
||||
buttonComp.setLayout(new GridLayout(2, false));
|
||||
buttonComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true,
|
||||
false));
|
||||
|
||||
GridData gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||
gd.widthHint = 75;
|
||||
Button okButton = new Button(buttonComp, SWT.PUSH);
|
||||
okButton.setText("OK");
|
||||
okButton.setLayoutData(gd);
|
||||
okButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
finish();
|
||||
handleOkAction();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
gd = new GridData(SWT.LEFT, SWT.DEFAULT, true, false);
|
||||
gd.widthHint = 75;
|
||||
Button cancelButton = new Button(buttonComp, SWT.PUSH);
|
||||
cancelButton.setText("Cancel");
|
||||
cancelButton.setLayoutData(gd);
|
||||
cancelButton.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
close();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void finish() {
|
||||
/**
|
||||
* Handle the OK action.
|
||||
*/
|
||||
private void handleOkAction() {
|
||||
if (validGroupName() == false) {
|
||||
return;
|
||||
}
|
||||
newGroup = nameText.getText();
|
||||
CollaborationConnection.getConnection().getContactsManager()
|
||||
.createGroup(newGroup);
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there was something entered in the text field.
|
||||
*
|
||||
* @return True if there is text in the group name text field.
|
||||
*/
|
||||
private boolean validGroupName() {
|
||||
if (nameText.getText().length() == 0) {
|
||||
MessageBox mb = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
|
||||
mb.setText("Invalid Name");
|
||||
mb.setMessage("You have not entered a group name. Please enter one.");
|
||||
mb.open();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the group name.
|
||||
*
|
||||
* @return The group name.
|
||||
*/
|
||||
public String getNewGroup() {
|
||||
return newGroup;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,9 +56,9 @@ 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.user.SharedDisplayRole;
|
||||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.PeerToPeerCommHelper;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CreateSessionData;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.PeerToPeerCommHelper;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.SharedDisplaySession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession;
|
||||
import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr;
|
||||
|
@ -93,6 +93,8 @@ import com.raytheon.viz.ui.editor.IMultiPaneEditor;
|
|||
* Feb 7, 2014 2699 bclement removed handle validation
|
||||
* Feb 11, 2014 2699 bclement require non-blank handle
|
||||
* Mar 06, 2014 2848 bclement moved session creation logic to separate method
|
||||
* Apr 16, 2014 3021 bclement increased width of dialog
|
||||
* Apr 22, 2014 3056 bclement made room name lowercase to match xmpp server
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -138,7 +140,7 @@ public class CreateSessionDialog extends CaveSWTDialog {
|
|||
label.setText("Name: ");
|
||||
nameTF = new Text(body, SWT.BORDER);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
gd.minimumWidth = 200;
|
||||
gd.minimumWidth = 300;
|
||||
nameTF.setLayoutData(gd);
|
||||
VerifyListener validNameListener = new VerifyListener() {
|
||||
|
||||
|
@ -451,7 +453,11 @@ public class CreateSessionDialog extends CaveSWTDialog {
|
|||
List<String> errorMessages = new ArrayList<String>();
|
||||
String subject = subjectTF.getText().trim();
|
||||
String err = validateVenueName();
|
||||
String name = nameTF.getText();
|
||||
/*
|
||||
* xmpp server lowercases all room names, lowercase here to
|
||||
* match when we get names back from the server
|
||||
*/
|
||||
String name = nameTF.getText().toLowerCase();
|
||||
if (err != null) {
|
||||
focusField = nameTF;
|
||||
errorMessages.add(err);
|
||||
|
|
|
@ -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.ui;
|
||||
|
||||
import org.eclipse.jface.dialogs.MessageDialog;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.ServerDisconnectEvent;
|
||||
import com.raytheon.uf.viz.collaboration.ui.actions.LogoutAction;
|
||||
import com.raytheon.uf.viz.collaboration.ui.login.LoginDialog;
|
||||
import com.raytheon.uf.viz.core.VizApp;
|
||||
|
||||
/**
|
||||
* Handles xmpp server disconnect events
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 11, 2014 2903 bclement Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bclement
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DisconnectHandler {
|
||||
|
||||
private static final String TITLE = "Disconnected from Collaboration Server";
|
||||
|
||||
private static final String DEFAULT_MESSAGE = "Click OK to re-login to the collaboration server";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public DisconnectHandler() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a disconnect from the xmpp server
|
||||
*
|
||||
* @param e
|
||||
*/
|
||||
@Subscribe
|
||||
public void serverDisconnected(final ServerDisconnectEvent e) {
|
||||
CollaborationConnection conn = CollaborationConnection.getConnection();
|
||||
if (conn == null) {
|
||||
// we aren't logged in
|
||||
return;
|
||||
}
|
||||
VizApp.runAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
/* close out existing collaboration components */
|
||||
LogoutAction.closeCollaboration();
|
||||
Shell shell = new Shell(Display.getCurrent());
|
||||
StringBuilder msg = new StringBuilder();
|
||||
String reason = e.getReason();
|
||||
if (reason != null && !reason.isEmpty()) {
|
||||
msg.append("Reason: ").append(reason).append('\n');
|
||||
}
|
||||
msg.append(DEFAULT_MESSAGE);
|
||||
/* inform the user of disconnect then re-login if requested */
|
||||
if (MessageDialog.openConfirm(shell, TITLE, msg.toString())
|
||||
&& new LoginDialog(shell).login()) {
|
||||
try {
|
||||
/* user has logged back in, put the view back */
|
||||
CollaborationGroupView.showView(true);
|
||||
} catch (PartInitException e) {
|
||||
Activator.statusHandler.error(
|
||||
"Problem restoring collaboration view", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -42,7 +42,7 @@ import com.raytheon.uf.viz.collaboration.comm.identity.invite.SharedDisplayVenue
|
|||
import com.raytheon.uf.viz.collaboration.comm.identity.invite.VenueInvite;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser;
|
||||
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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.SharedDisplaySession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueId;
|
||||
|
@ -67,6 +67,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialogBase;
|
|||
* Feb 13, 2014 2751 bclement better types for roomid and inviter
|
||||
* Mar 06, 2014 2848 bclement moved join logic to separate method
|
||||
* Mar 27, 2014 2632 mpduff Set the OK button as the default button.
|
||||
* Apr 18, 2014 2955 mpduff Make dialog non-modal.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -105,18 +106,11 @@ public class InviteDialog extends CaveSWTDialogBase {
|
|||
*
|
||||
* @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.
|
||||
* @param event
|
||||
* The invitation event
|
||||
*/
|
||||
public InviteDialog(Shell parentShell, IVenueInvitationEvent event) {
|
||||
super(parentShell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL
|
||||
| SWT.PRIMARY_MODAL | SWT.SYSTEM_MODAL, CAVE.NONE);
|
||||
super(parentShell, SWT.DIALOG_TRIM, CAVE.NONE);
|
||||
setText("Session Invitation");
|
||||
IUser inviter = event.getInviter();
|
||||
VenueId room = event.getRoomId();
|
||||
|
@ -151,7 +145,7 @@ public class InviteDialog extends CaveSWTDialogBase {
|
|||
@Override
|
||||
protected void initializeComponents(Shell shell) {
|
||||
mainComp = new Composite(shell, SWT.NONE);
|
||||
GridLayout gl = new GridLayout(2, false);
|
||||
GridLayout gl = new GridLayout(1, false);
|
||||
gl.marginHeight = 0;
|
||||
gl.marginWidth = 0;
|
||||
gl.horizontalSpacing = 0;
|
||||
|
@ -233,10 +227,10 @@ public class InviteDialog extends CaveSWTDialogBase {
|
|||
font = new Font(Display.getCurrent(), fontData[0]);
|
||||
}
|
||||
if (heading) {
|
||||
gd = new GridData(SWT.LEFT, SWT.NONE, false, false);
|
||||
gd = new GridData(SWT.LEFT, SWT.CENTER, false, false);
|
||||
label.setFont(font);
|
||||
} else {
|
||||
gd = new GridData(SWT.LEFT, SWT.NONE, true, true);
|
||||
gd = new GridData(SWT.LEFT, SWT.CENTER, true, true);
|
||||
gd.widthHint = 300;
|
||||
}
|
||||
label.setLayoutData(gd);
|
||||
|
@ -250,16 +244,15 @@ public class InviteDialog extends CaveSWTDialogBase {
|
|||
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() {
|
||||
Button joinBtn = new Button(actionButtonComp, SWT.PUSH);
|
||||
joinBtn.setText("Join");
|
||||
joinBtn.setLayoutData(gd);
|
||||
joinBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent se) {
|
||||
String handle = handleText.getText().trim();
|
||||
|
@ -294,7 +287,7 @@ public class InviteDialog extends CaveSWTDialogBase {
|
|||
}
|
||||
});
|
||||
|
||||
this.getShell().setDefaultButton(okBtn);
|
||||
this.getShell().setDefaultButton(joinBtn);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -340,6 +333,11 @@ public class InviteDialog extends CaveSWTDialogBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the IVenueSession being used.
|
||||
*
|
||||
* @return the IVenueSession
|
||||
*/
|
||||
public IVenueSession getSession() {
|
||||
return session;
|
||||
}
|
||||
|
|
|
@ -34,10 +34,11 @@ import org.eclipse.swt.widgets.Combo;
|
|||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Layout;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.jivesoftware.smack.RosterGroup;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||
|
||||
/**
|
||||
|
@ -54,6 +55,10 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* Jan 31, 2014 2700 bclement don't prompt for group if user is already in one
|
||||
* Feb 13, 2014 2755 bclement roster addition now done in account manager, user input passed back
|
||||
* Apr 07, 2014 2785 mpduff Changed to implement CaveSWTDialog
|
||||
* Fix loading of groups
|
||||
* Apr 23, 2014 3040 lvenable Cleaned up dialog code/layout. Allow the cancellation of the create
|
||||
* group dialog without closing this dialog. Added capability to resize
|
||||
* the group combo box if the names get too long.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -61,12 +66,19 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
|||
* @version 1.0
|
||||
*/
|
||||
public class SubRequestDialog extends CaveSWTDialog {
|
||||
private final String NEW_GROUP = "New Group...";
|
||||
|
||||
/** User ID. */
|
||||
private final String userid;
|
||||
|
||||
/** Combo listing all of the available groups. */
|
||||
private Combo groupCbo;
|
||||
|
||||
/** Create group dialog. */
|
||||
private CreateGroupDialog createGroupDlg;
|
||||
|
||||
/** Allow button. */
|
||||
private Button allowBtn;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -79,35 +91,70 @@ public class SubRequestDialog extends CaveSWTDialog {
|
|||
setText("Contact Request");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Layout constructShellLayout() {
|
||||
GridLayout mainLayout = new GridLayout(1, false);
|
||||
return mainLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object constructShellLayoutData() {
|
||||
return new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeComponents(Shell shell) {
|
||||
GridLayout gl = new GridLayout(1, false);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
Composite mainComp = new Composite(shell, SWT.NONE);
|
||||
GridLayout gl = new GridLayout(1, false);
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
mainComp.setLayout(gl);
|
||||
mainComp.setLayoutData(gd);
|
||||
|
||||
/*
|
||||
* Top Label
|
||||
*/
|
||||
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
|
||||
Label msgLbl = new Label(mainComp, SWT.NONE);
|
||||
msgLbl.setText(userid + " wants to add you to their contacts list.");
|
||||
msgLbl.setText(userid + " wants to add you to a contacts list:");
|
||||
msgLbl.setLayoutData(gd);
|
||||
|
||||
gl = new GridLayout(2, false);
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
/*
|
||||
* Group composite and controls.
|
||||
*/
|
||||
Composite groupComp = new Composite(mainComp, SWT.NONE);
|
||||
gl = new GridLayout(3, false);
|
||||
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
groupComp.setLayout(gl);
|
||||
groupComp.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||
gd = new GridData(SWT.DEFAULT, SWT.CENTER, false, true);
|
||||
Label groupLbl = new Label(groupComp, SWT.NONE);
|
||||
groupLbl.setText("Group: ");
|
||||
groupLbl.setLayoutData(gd);
|
||||
|
||||
gd = new GridData(SWT.FILL, SWT.CENTER, true, true);
|
||||
gd.minimumWidth = 130;
|
||||
groupCbo = new Combo(groupComp, SWT.DROP_DOWN | SWT.READ_ONLY);
|
||||
groupCbo.setItems(getGroupNames());
|
||||
groupCbo.select(0);
|
||||
groupCbo.setLayout(gl);
|
||||
groupCbo.setLayoutData(gd);
|
||||
|
||||
gd = new GridData();
|
||||
gd.horizontalIndent = 5;
|
||||
Button newGroup = new Button(groupComp, SWT.PUSH);
|
||||
newGroup.setText("New Group...");
|
||||
newGroup.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
handleNewGroupAction();
|
||||
}
|
||||
});
|
||||
|
||||
addSeparator(mainComp);
|
||||
|
||||
/*
|
||||
* Action buttons.
|
||||
*/
|
||||
gl = new GridLayout(2, false);
|
||||
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
|
||||
Composite btnComp = new Composite(mainComp, SWT.NONE);
|
||||
|
@ -117,16 +164,21 @@ public class SubRequestDialog extends CaveSWTDialog {
|
|||
int btnWidth = 75;
|
||||
|
||||
gd = new GridData(btnWidth, SWT.DEFAULT);
|
||||
Button allowBtn = new Button(btnComp, SWT.PUSH);
|
||||
allowBtn = new Button(btnComp, SWT.PUSH);
|
||||
allowBtn.setText("Allow");
|
||||
allowBtn.setLayoutData(gd);
|
||||
allowBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
action(true);
|
||||
handleAllowDenyAction(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Disable the allow button if there are no items in the combo box.
|
||||
if (groupCbo.getItemCount() == 0) {
|
||||
allowBtn.setEnabled(false);
|
||||
}
|
||||
|
||||
gd = new GridData(btnWidth, SWT.DEFAULT);
|
||||
Button denyBtn = new Button(btnComp, SWT.PUSH);
|
||||
denyBtn.setText("Deny");
|
||||
|
@ -134,12 +186,14 @@ public class SubRequestDialog extends CaveSWTDialog {
|
|||
denyBtn.addSelectionListener(new SelectionAdapter() {
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
action(false);
|
||||
handleAllowDenyAction(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of group names.
|
||||
*
|
||||
* @return list of existing group names
|
||||
*/
|
||||
private String[] getGroupNames() {
|
||||
|
@ -148,36 +202,53 @@ public class SubRequestDialog extends CaveSWTDialog {
|
|||
if (connection == null) {
|
||||
return new String[0];
|
||||
}
|
||||
Collection<RosterGroup> groups = connection.getContactsManager()
|
||||
Collection<RosterGroup> rosterGroups = connection.getContactsManager()
|
||||
.getGroups();
|
||||
List<String> groupList = new ArrayList<String>(groups.size());
|
||||
for (String group : groupList) {
|
||||
groupList.add(group);
|
||||
List<String> groupList = new ArrayList<String>(rosterGroups.size());
|
||||
for (RosterGroup group : rosterGroups) {
|
||||
groupList.add(group.getName());
|
||||
}
|
||||
|
||||
Collections.sort(groupList);
|
||||
groupList.add(0, NEW_GROUP);
|
||||
|
||||
return groupList.toArray(new String[groupList.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action handler.
|
||||
*
|
||||
* @param approved
|
||||
* true if request approved, false if denied
|
||||
* Handle adding a new group.
|
||||
*/
|
||||
private void action(boolean approved) {
|
||||
if (approved) {
|
||||
if (groupCbo.getSelectionIndex() == 0) {
|
||||
// new group
|
||||
CreateGroupDialog dialog = new CreateGroupDialog(Display
|
||||
.getCurrent().getActiveShell());
|
||||
dialog.open();
|
||||
String group = dialog.getNewGroup();
|
||||
setReturnValue(group);
|
||||
} else {
|
||||
private void handleNewGroupAction() {
|
||||
if (createGroupDlg == null || createGroupDlg.isDisposed()) {
|
||||
createGroupDlg = new CreateGroupDialog(Display.getCurrent()
|
||||
.getActiveShell());
|
||||
createGroupDlg.open();
|
||||
String groupName = createGroupDlg.getNewGroup();
|
||||
|
||||
// If the group name is not null, add it to the combo and then
|
||||
// select it.
|
||||
if (groupName != null) {
|
||||
allowBtn.setEnabled(true);
|
||||
groupCbo.add(groupName, 0);
|
||||
groupCbo.select(0);
|
||||
shell.pack();
|
||||
}
|
||||
} else {
|
||||
createGroupDlg.bringToTop();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Allow/Deny action.
|
||||
*
|
||||
* @param allowRequest
|
||||
* True if request allowed, false if denied
|
||||
*/
|
||||
private void handleAllowDenyAction(boolean allowRequest) {
|
||||
if (allowRequest) {
|
||||
if (groupCbo.getItemCount() != 0) {
|
||||
setReturnValue(groupCbo.getItem(groupCbo.getSelectionIndex()));
|
||||
} else {
|
||||
|
||||
}
|
||||
} else {
|
||||
setReturnValue(null);
|
||||
|
@ -185,4 +256,19 @@ public class SubRequestDialog extends CaveSWTDialog {
|
|||
|
||||
close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a line separator to the given composite.
|
||||
*
|
||||
* @param parentComp
|
||||
* Parent composite.
|
||||
*/
|
||||
private void addSeparator(Composite parentComp) {
|
||||
GridLayout gl = (GridLayout) parentComp.getLayout();
|
||||
|
||||
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||
gd.horizontalSpan = gl.numColumns;
|
||||
Label sepLbl = new Label(parentComp, SWT.SEPARATOR | SWT.HORIZONTAL);
|
||||
sepLbl.setLayoutData(gd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ import org.jivesoftware.smack.XMPPException;
|
|||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserSearch;
|
||||
import com.raytheon.uf.viz.collaboration.ui.actions.AddToGroupAction;
|
||||
|
|
|
@ -31,8 +31,7 @@ import org.eclipse.jface.viewers.ViewerFilter;
|
|||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.RosterGroup;
|
||||
|
||||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.SharedGroup;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.ui.data.CollaborationGroupContainer;
|
||||
|
@ -51,6 +50,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.SessionGroupContainer;
|
|||
* Dec 6, 2013 2561 bclement removed ECF
|
||||
* Jan 24, 2014 2701 bclement removed local groups, added shared groups
|
||||
* Jan 27, 2014 2700 bclement added support roster entries
|
||||
* Apr 24, 2014 3070 bclement removed check for hasInteraction() from group entries
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -141,8 +141,7 @@ public class UsersTreeContentProvider implements ITreeContentProvider {
|
|||
UserId localUser = connection.getUser();
|
||||
for (RosterEntry entry : entries) {
|
||||
String user = entry.getUser();
|
||||
if (!localUser.isSameUser(user)
|
||||
&& ContactsManager.hasInteraction(entry)) {
|
||||
if (!localUser.isSameUser(user)) {
|
||||
result.add(entry);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ import org.jivesoftware.smack.packet.Presence;
|
|||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.IVenueSession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.info.IVenue;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
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.SharedGroup;
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.jivesoftware.smack.RosterEntry;
|
|||
import org.jivesoftware.smack.RosterGroup;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
|
||||
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.IDConverter;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
|
@ -51,6 +51,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
|
|||
* Jul 3, 2012 bsteffen Initial creation
|
||||
* Dec 20, 2013 2563 bclement added support for ungrouped roster entries
|
||||
* Jan 24, 2014 2701 bclement removed local groups
|
||||
* Apr 24, 2014 3070 bclement RosterChangeEvent changes
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -114,8 +115,9 @@ public class AddToGroupAction extends Action {
|
|||
if (entry != null) {
|
||||
// the entry wasn't in a group, so the entire tree needs to be
|
||||
// refreshed
|
||||
UserId entryId = IDConverter.convertFrom(entry);
|
||||
connection.postEvent(new RosterChangeEvent(RosterChangeType.MODIFY,
|
||||
entry));
|
||||
entryId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ 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.comm.provider.connection.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;
|
||||
|
|
|
@ -26,7 +26,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.core.icon.IconUtil;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.ChangePasswordDialog;
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager;
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.SiteConfigurationManager;
|
||||
import com.raytheon.uf.viz.collaboration.ui.session.SubscribeList;
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ 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.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.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;
|
||||
|
|
|
@ -28,7 +28,7 @@ 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.Tools;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.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;
|
||||
|
|
|
@ -28,11 +28,8 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
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
|
||||
|
@ -45,6 +42,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 1, 2012 rferrel Initial creation
|
||||
* Mar 05, 2014 2798 mpduff Don't create a new DisplayFeedAction
|
||||
* Apr 11, 2014 2903 bclement moved collaboration view init to CollaborationGroupView
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -62,27 +60,12 @@ public class CollaborationGroupAction extends AbstractHandler {
|
|||
// If connection is null then user has not logged in
|
||||
boolean initialExecutionFlag = CollaborationConnection
|
||||
.getConnection() == null;
|
||||
new LoginAction().run();
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
if (connection == null) {
|
||||
if (!new LoginAction().login()) {
|
||||
// user cancelled login
|
||||
return event;
|
||||
}
|
||||
|
||||
CollaborationGroupView view = (CollaborationGroupView) CaveWorkbenchPageManager
|
||||
.getActiveInstance().showView(CollaborationGroupView.ID);
|
||||
|
||||
// Is this is the first log in
|
||||
if (initialExecutionFlag) {
|
||||
// if autojoin is selected (to join the default room)
|
||||
if (Activator.getDefault().getPreferenceStore()
|
||||
.getBoolean(CollabPrefConstants.AUTO_JOIN)) {
|
||||
DisplayFeedAction action = view.getDisplayFeedAction();
|
||||
action.setChecked(true);
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
CollaborationGroupView.showView(initialExecutionFlag);
|
||||
} catch (PartInitException e) {
|
||||
statusHandler.handle(Priority.PROBLEM,
|
||||
"Unable to open collaboration contact list", e);
|
||||
|
|
|
@ -22,7 +22,7 @@ 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.comm.provider.connection.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.CreateGroupDialog;
|
||||
|
|
|
@ -29,7 +29,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CreateSessionData;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
|
|
|
@ -21,7 +21,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.core.icon.IconUtil;
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.VenueSession;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.collaboration.ui.prefs.HandleUtil;
|
||||
|
|
|
@ -42,7 +42,7 @@ 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.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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
||||
import com.raytheon.uf.viz.collaboration.display.data.SharedDisplaySessionMgr;
|
||||
|
|
|
@ -32,7 +32,7 @@ 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.comm.provider.connection.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;
|
||||
|
|
|
@ -23,7 +23,7 @@ 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.comm.provider.connection.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;
|
||||
|
@ -38,6 +38,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 11, 2012 bsteffen Initial creation
|
||||
* Apr 11, 2014 2903 bclement added success flag
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -46,6 +47,8 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
|
|||
*/
|
||||
|
||||
public class LoginAction extends Action {
|
||||
|
||||
private boolean success = false;
|
||||
|
||||
public LoginAction() {
|
||||
super("Login...", IconUtil.getImageDescriptor(Activator.getDefault()
|
||||
|
@ -62,9 +65,24 @@ public class LoginAction extends Action {
|
|||
if (shell == null) {
|
||||
return;
|
||||
}
|
||||
LoginDialog dlg = new LoginDialog(shell);
|
||||
dlg.open();
|
||||
success = new LoginDialog(shell).login();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the success
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to run action and return results
|
||||
*
|
||||
* @return true if login was successful
|
||||
*/
|
||||
public boolean login() {
|
||||
this.run();
|
||||
return isSuccess();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ 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.comm.provider.connection.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;
|
||||
|
@ -54,6 +54,7 @@ import com.raytheon.viz.ui.views.CaveWorkbenchPageManager;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 11, 2012 bsteffen Initial creation
|
||||
* Dec 19, 2013 2563 bclement moved close logic to public method
|
||||
* Apr 11, 2014 2903 bclement made close method static, added safety check
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -90,7 +91,7 @@ public class LogoutAction extends Action {
|
|||
* Close collaboration UI and close connection
|
||||
*
|
||||
*/
|
||||
public void closeCollaboration() {
|
||||
public static void closeCollaboration() {
|
||||
for (IViewReference ref : CaveWorkbenchPageManager.getActiveInstance()
|
||||
.getViewReferences()) {
|
||||
IViewPart view = ref.getView(false);
|
||||
|
@ -118,8 +119,10 @@ public class LogoutAction extends Action {
|
|||
}
|
||||
CollaborationConnection connection = CollaborationConnection
|
||||
.getConnection();
|
||||
ConnectionSubscriber.unsubscribe(connection);
|
||||
connection.close();
|
||||
if (connection != null) {
|
||||
ConnectionSubscriber.unsubscribe(connection);
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.jivesoftware.smack.packet.Presence.Type;
|
|||
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.connection.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.PeerToPeerView;
|
||||
|
|
|
@ -21,7 +21,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
|
|
|
@ -23,9 +23,11 @@ import org.eclipse.jface.action.Action;
|
|||
import org.jivesoftware.smack.RosterEntry;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.event.RosterChangeType;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.event.RosterChangeEvent;
|
||||
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.IDConverter;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.core.icon.IconUtil;
|
||||
|
||||
|
@ -40,6 +42,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 20, 2013 2563 bclement Initial creation
|
||||
* Mar 05, 2014 2837 bclement changed wording from Roster to Contacts, added image
|
||||
* Apr 24, 2014 3070 bclement RosterChangeEvent changes
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -64,7 +67,8 @@ public class RemoveFromRosterAction extends Action {
|
|||
ContactsManager manager = connection
|
||||
.getContactsManager();
|
||||
manager.removeFromRoster(entry);
|
||||
UserId entryId = IDConverter.convertFrom(entry);
|
||||
connection.postEvent(new RosterChangeEvent(RosterChangeType.DELETE,
|
||||
entry));
|
||||
entryId));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,10 @@ package com.raytheon.uf.viz.collaboration.ui.actions;
|
|||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.jivesoftware.smack.RosterEntry;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Presence.Type;
|
||||
|
||||
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.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
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.ui.Activator;
|
||||
import com.raytheon.uf.viz.core.icon.IconUtil;
|
||||
|
@ -42,6 +40,7 @@ import com.raytheon.uf.viz.core.icon.IconUtil;
|
|||
* ------------ ---------- ----------- --------------------------
|
||||
* Jan 24, 2014 bclement Initial creation
|
||||
* Mar 05, 2014 2837 bclement added image
|
||||
* Apr 24, 2014 3070 bclement moved contact request logic to contacts manager
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -71,10 +70,9 @@ public class SendSubReqAction extends Action {
|
|||
@Override
|
||||
public void run() {
|
||||
CollaborationConnection connection = CollaborationConnection.getConnection();
|
||||
IAccountManager manager = connection.getAccountManager();
|
||||
ContactsManager manager = connection.getContactsManager();
|
||||
try {
|
||||
manager.sendPresence(IDConverter.convertFrom(entry), new Presence(
|
||||
Type.subscribe));
|
||||
manager.sendContactRequest(IDConverter.convertFrom(entry));
|
||||
} catch (CollaborationException e) {
|
||||
Activator.statusHandler.error(
|
||||
"Unable to send subscription request", e);
|
||||
|
|
|
@ -22,7 +22,7 @@ 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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.collaboration.ui.UserSearchDialog;
|
||||
import com.raytheon.uf.viz.core.icon.IconUtil;
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,7 +26,7 @@ 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;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
|
||||
/**
|
||||
* Retrieve session objects from contacts list
|
||||
|
|
|
@ -51,7 +51,9 @@ import com.raytheon.viz.ui.panes.VizDisplayPane;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 7, 2012 mschenke Initial creation
|
||||
* Jun 07, 2012 mschenke Initial creation
|
||||
* Apr 23, 2014 3060 njensen Safety checks for SWT widgets disposed
|
||||
* May 01, 2014 2956 njensen More safety checks for SWT widgets disposed
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -179,11 +181,14 @@ public class CollaborationPaneManager extends PaneManager {
|
|||
setExclude(activeData, true);
|
||||
activeData = null;
|
||||
}
|
||||
noDisplayLabel.setVisible(true);
|
||||
((GridData) noDisplayLabel.getLayoutData()).exclude = false;
|
||||
composite.layout();
|
||||
if (!noDisplayLabel.isDisposed() && !composite.isDisposed()) {
|
||||
noDisplayLabel.setVisible(true);
|
||||
((GridData) noDisplayLabel.getLayoutData()).exclude = false;
|
||||
composite.layout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void adjustPaneLayout(int paneCount) {
|
||||
;// don't do anything, we always want one pane displayed.
|
||||
}
|
||||
|
@ -238,7 +243,9 @@ public class CollaborationPaneManager extends PaneManager {
|
|||
|
||||
public void setCanvasSize(IRenderableDisplay display, Rectangle bounds) {
|
||||
DisplayData data = displayMap.get(display);
|
||||
if (data == null) {
|
||||
if (data == null || data.canvasComp.isDisposed()
|
||||
|| data.scrollable.isDisposed()
|
||||
|| data.wrapperComp.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
data.canvasBounds = bounds;
|
||||
|
@ -269,9 +276,11 @@ public class CollaborationPaneManager extends PaneManager {
|
|||
}
|
||||
|
||||
private void setExclude(DisplayData data, boolean exclude) {
|
||||
GridData gd = (GridData) data.scrollable.getLayoutData();
|
||||
data.scrollable.setVisible(!exclude);
|
||||
gd.exclude = exclude;
|
||||
if (!data.scrollable.isDisposed()) {
|
||||
GridData gd = (GridData) data.scrollable.getLayoutData();
|
||||
data.scrollable.setVisible(!exclude);
|
||||
gd.exclude = exclude;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import com.raytheon.uf.common.status.UFStatus;
|
|||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.CollaborationException;
|
||||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
|
||||
|
||||
|
|
|
@ -52,8 +52,9 @@ import com.raytheon.uf.viz.collaboration.comm.identity.info.SiteConfigInformatio
|
|||
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.Tools;
|
||||
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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnectionData;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ResourceInfo;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.collaboration.ui.CollaborationUtils;
|
||||
import com.raytheon.uf.viz.collaboration.ui.ConnectionSubscriber;
|
||||
|
@ -75,6 +76,9 @@ import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants;
|
|||
* Jan 08, 2014 2563 bclement added Add/Remove buttons for server list
|
||||
* Jan 15, 2014 2630 bclement connection data stores status as Mode object
|
||||
* Apr 07, 2014 2785 mpduff Implemented change to CollaborationConnection
|
||||
* Apr 11, 2014 2903 bclement added success flag, moved login logic to static method
|
||||
* fixed populating server with previous, removed password from heap
|
||||
* Apr 23, 2014 2822 bclement added version to initial presence
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -110,6 +114,8 @@ public class LoginDialog extends Dialog {
|
|||
|
||||
private Shell shell;
|
||||
|
||||
private boolean success = false;
|
||||
|
||||
/**
|
||||
* @param parentShell
|
||||
*/
|
||||
|
@ -179,10 +185,11 @@ public class LoginDialog extends Dialog {
|
|||
Iterator<HostConfig> iter = Iterators.concat(siteServers.iterator(),
|
||||
userServers.iterator());
|
||||
int index = 0;
|
||||
String prevServer = loginData.getServer();
|
||||
for (int i = 0; iter.hasNext() && i < names.length; i++) {
|
||||
HostConfig config = iter.next();
|
||||
names[i] = config.toString();
|
||||
if (loginData.getServer().equals(names[i])) {
|
||||
if (config.getHostname().equals(prevServer)) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +327,7 @@ public class LoginDialog extends Dialog {
|
|||
@Override
|
||||
public void widgetSelected(SelectionEvent event) {
|
||||
loginData.setUserName(userText.getText().trim());
|
||||
loginData.setPassword(passwordText.getText().trim());
|
||||
String password = passwordText.getText().trim();
|
||||
loginData.setServer(HostConfig.removeDescription(serverText
|
||||
.getText()));
|
||||
loginData.setStatus(CollaborationUtils.parseMode(statusCombo
|
||||
|
@ -347,7 +354,7 @@ public class LoginDialog extends Dialog {
|
|||
}
|
||||
loginData.setServer(server);
|
||||
|
||||
if (loginData.getPassword().isEmpty()) {
|
||||
if (password.isEmpty()) {
|
||||
errorMessages.add("Must enter a password.");
|
||||
}
|
||||
|
||||
|
@ -365,38 +372,10 @@ public class LoginDialog extends Dialog {
|
|||
messageBox.setMessage(sb.toString());
|
||||
messageBox.open();
|
||||
} else {
|
||||
try {
|
||||
// Create the connection
|
||||
CollaborationConnection collabConnection = CollaborationConnection
|
||||
.createConnection(loginData);
|
||||
|
||||
// Subscribe to the collaboration connection
|
||||
ConnectionSubscriber.subscribe(collabConnection);
|
||||
|
||||
// Connect to the XMPP server
|
||||
collabConnection.connect();
|
||||
|
||||
success = login(loginData, password);
|
||||
if (success) {
|
||||
storeLoginData();
|
||||
shell.dispose();
|
||||
|
||||
// send initial presence
|
||||
Mode mode = loginData.getStatus();
|
||||
if (mode == null) {
|
||||
mode = Mode.available;
|
||||
}
|
||||
|
||||
Presence initialPresence = new Presence(Type.available,
|
||||
loginData.getMessage(), 0, mode);
|
||||
Tools.setProperties(initialPresence,
|
||||
loginData.getAttributes());
|
||||
|
||||
collabConnection.getAccountManager().sendPresence(
|
||||
initialPresence);
|
||||
|
||||
} catch (CollaborationException e) {
|
||||
Activator.statusHandler.handle(Priority.PROBLEM,
|
||||
"Error connecting to collaboration server: "
|
||||
+ e.getLocalizedMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -414,6 +393,62 @@ public class LoginDialog extends Dialog {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to login to xmpp server.
|
||||
*
|
||||
* @param loginData
|
||||
* @param password
|
||||
* @return true if login was successful
|
||||
*/
|
||||
public static boolean login(CollaborationConnectionData loginData,
|
||||
String password) {
|
||||
CollaborationConnection collabConnection = null;
|
||||
boolean rval = false;
|
||||
boolean subscribed = false;
|
||||
try {
|
||||
// Create the connection
|
||||
collabConnection = CollaborationConnection
|
||||
.createConnection(loginData);
|
||||
|
||||
// Subscribe to the collaboration connection
|
||||
ConnectionSubscriber.subscribe(collabConnection);
|
||||
subscribed = true;
|
||||
|
||||
// Login to the XMPP server
|
||||
collabConnection.login(password);
|
||||
|
||||
/* login was success, other errors are recoverable */
|
||||
rval = true;
|
||||
|
||||
// send initial presence
|
||||
Mode mode = loginData.getStatus();
|
||||
if (mode == null) {
|
||||
mode = Mode.available;
|
||||
}
|
||||
|
||||
Presence initialPresence = new Presence(Type.available,
|
||||
loginData.getMessage(), 0, mode);
|
||||
Tools.setProperties(initialPresence, loginData.getAttributes());
|
||||
initialPresence.setProperty(ResourceInfo.VERSION_KEY,
|
||||
CollaborationConnection.getCollaborationVersion());
|
||||
collabConnection.getAccountManager().sendPresence(initialPresence);
|
||||
|
||||
} catch (CollaborationException e) {
|
||||
if (subscribed && collabConnection != null) {
|
||||
ConnectionSubscriber.unsubscribe(collabConnection);
|
||||
}
|
||||
String msg;
|
||||
if (rval) {
|
||||
msg = "Error sending initial presence to collaboration server";
|
||||
} else {
|
||||
msg = "Error connecting to collaboration server: "
|
||||
+ e.getLocalizedMessage();
|
||||
}
|
||||
Activator.statusHandler.handle(Priority.PROBLEM, msg, e);
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
private void storeLoginData() {
|
||||
preferences.setValue(CollabPrefConstants.P_USERNAME,
|
||||
loginData.getUserName());
|
||||
|
@ -435,4 +470,21 @@ public class LoginDialog extends Dialog {
|
|||
loginData.setMessage(preferences
|
||||
.getString(CollabPrefConstants.P_MESSAGE));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the success
|
||||
*/
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to open dialog and return true if login was successful
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean login() {
|
||||
open();
|
||||
return isSuccess();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ 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.util.FileUtil;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.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.core.sounds.SoundUtil;
|
||||
|
|
|
@ -34,6 +34,7 @@ package com.raytheon.uf.viz.collaboration.ui.prefs;
|
|||
* Feb 3, 2014 2699 bclement added handle preferences
|
||||
* Feb 18, 2014 2631 mpduff Add constants for room change events.
|
||||
* Mar 24, 2014 2936 mpduff Remove INCLUDE_NWS_FEED_FIELD_EDITOR_ID.
|
||||
* Apr 24, 2014 3070 bclement added DEFAULT_GROUPNAME_PREF
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -62,6 +63,8 @@ public class CollabPrefConstants {
|
|||
|
||||
public static final String CUSTOM_HANDLE = "customHandle";
|
||||
|
||||
public static final String DEFAULT_GROUPNAME_PREF = "defaultGroupName";
|
||||
|
||||
public static final int AWAY_TIMEOUT_DEFAULT = 10; // ten minutes
|
||||
|
||||
/** Enable join events field editor id */
|
||||
|
|
|
@ -50,7 +50,7 @@ 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.comm.provider.connection.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;
|
||||
|
|
|
@ -28,7 +28,7 @@ import org.eclipse.jface.preference.StringFieldEditor;
|
|||
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.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
import com.raytheon.uf.viz.collaboration.ui.prefs.CollabPrefConstants.HandleOption;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ import org.jivesoftware.smack.RosterEntry;
|
|||
import org.jivesoftware.smack.RosterGroup;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
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.SharedGroup;
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.jivesoftware.smack.packet.Presence;
|
|||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
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.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserSearch;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.collaboration.ui.prefs;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -27,15 +26,15 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import org.eclipse.jface.preference.IPersistentPreferenceStore;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.jivesoftware.smack.RosterGroup;
|
||||
import org.jivesoftware.smack.XMPPException;
|
||||
|
||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.roster.ISubscriptionResponder;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.roster.SubscriptionResponse;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.ISubscriptionRequestCompleteAction;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.account.ISubscriptionRequestCompleteAction;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.ContactsManager;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserSearch;
|
||||
import com.raytheon.uf.viz.collaboration.ui.Activator;
|
||||
|
@ -52,6 +51,8 @@ import com.raytheon.uf.viz.core.VizApp;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Apr 03, 2014 2785 mpduff Initial creation
|
||||
* Apr 24, 2014 3070 bclement added default group for auto accept
|
||||
* fixed auto accept known contacts
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -88,15 +89,16 @@ public class SubscriptionResponderImpl implements ISubscriptionResponder {
|
|||
.getPreferenceStore();
|
||||
if (prefs.getBoolean(CollabPrefConstants.AUTO_ACCEPT_SUBSCRIBE)) {
|
||||
rval.setAccepted(true);
|
||||
rval.setGroup(prefs
|
||||
.getString(CollabPrefConstants.DEFAULT_GROUPNAME_PREF));
|
||||
action.executeSubscriptionRequestComplete(fromID, rval);
|
||||
return;
|
||||
}
|
||||
|
||||
CollaborationConnection conn = CollaborationConnection.getConnection();
|
||||
Collection<RosterGroup> groups = conn.getContactsManager().getGroups(
|
||||
fromID);
|
||||
if (!groups.isEmpty()) {
|
||||
// we already have this user in a group in our roster
|
||||
ContactsManager cm = conn.getContactsManager();
|
||||
if (cm.isContact(fromID)) {
|
||||
/* we already have a subscription to this user */
|
||||
rval.setAccepted(true);
|
||||
action.executeSubscriptionRequestComplete(fromID, rval);
|
||||
} else {
|
||||
|
|
|
@ -57,7 +57,7 @@ import com.google.common.eventbus.Subscribe;
|
|||
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.IMessage;
|
||||
import com.raytheon.uf.viz.collaboration.comm.identity.user.IUser;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.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;
|
||||
|
|
|
@ -21,6 +21,7 @@ package com.raytheon.uf.viz.collaboration.ui.session;
|
|||
**/
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -100,6 +101,8 @@ import com.raytheon.viz.ui.input.EditableManager;
|
|||
* Mar 06, 2014 2848 bclement moved colormanager update code to session container
|
||||
* Mar 11, 2014 2865 lvenable Added null checks in threads
|
||||
* Mar 18, 2014 2895 njensen Fix lockAction enable/disable logic
|
||||
* Apr 15, 2014 2822 bclement only allow transfer leader if participant is using shared display
|
||||
* May 05, 2014 3076 bclement added clear all action
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -139,6 +142,8 @@ public class CollaborationSessionView extends SessionView implements
|
|||
|
||||
private ActionContributionItem lockAction;
|
||||
|
||||
private ActionContributionItem clearAllAction;
|
||||
|
||||
private ControlContribution noEditorAction;
|
||||
|
||||
private ISharedDisplaySession session;
|
||||
|
@ -180,6 +185,21 @@ public class CollaborationSessionView extends SessionView implements
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see CollaborationDrawingResource#getAllDrawingLayers()
|
||||
* @return empty collection if no layers are found
|
||||
*/
|
||||
private Collection<DrawingToolLayer> getAllLayers() {
|
||||
Collection<DrawingToolLayer> rval;
|
||||
CollaborationDrawingResource resource = getCurrentDrawingResource();
|
||||
if (resource != null) {
|
||||
rval = resource.getAllDrawingLayers();
|
||||
} else {
|
||||
rval = Collections.emptyList();
|
||||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
@ -353,7 +373,15 @@ public class CollaborationSessionView extends SessionView implements
|
|||
lockAction.getAction().setImageDescriptor(
|
||||
IconUtil.getImageDescriptor(Activator.getDefault().getBundle(),
|
||||
"lock.gif"));
|
||||
|
||||
clearAllAction = new ActionContributionItem(new Action("Clear All") {
|
||||
@Override
|
||||
public void run() {
|
||||
clearAllDrawingLayers();
|
||||
}
|
||||
});
|
||||
clearAllAction.getAction().setImageDescriptor(
|
||||
IconUtil.getImageDescriptor(Activator.getDefault().getBundle(),
|
||||
"clear_all.gif"));
|
||||
noEditorAction = new ControlContribution("noEditorAction") {
|
||||
|
||||
@Override
|
||||
|
@ -382,12 +410,30 @@ public class CollaborationSessionView extends SessionView implements
|
|||
mgr.insert(mgr.getSize() - 1, redoAction);
|
||||
mgr.insert(mgr.getSize() - 1, clearAction);
|
||||
mgr.insert(mgr.getSize() - 1, eraseAction);
|
||||
mgr.insert(mgr.getSize() - 1, new Separator());
|
||||
mgr.insert(mgr.getSize() - 1, lockAction);
|
||||
mgr.insert(mgr.getSize() - 1, clearAllAction);
|
||||
mgr.insert(mgr.getSize() - 1, new Separator());
|
||||
|
||||
updateToolItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all drawing layers and send clear all event
|
||||
*/
|
||||
private void clearAllDrawingLayers() {
|
||||
for (DrawingToolLayer layer : getAllLayers()) {
|
||||
layer.clearAllDrawingData();
|
||||
}
|
||||
CollaborationDrawingResource resource = getCurrentDrawingResource();
|
||||
CollaborationDrawingEvent event = new CollaborationDrawingEvent(
|
||||
resource.getResourceData().getDisplayId());
|
||||
event.setType(CollaborationEventType.CLEAR_ALL);
|
||||
event.setUserName(resource.getMyUser());
|
||||
resource.sendEvent(event);
|
||||
updateToolItems();
|
||||
}
|
||||
|
||||
private void toggleDrawMode(DrawMode mode) {
|
||||
if (mode != DrawMode.NONE) {
|
||||
CollaborationDrawingResource resource = getCurrentDrawingResource();
|
||||
|
@ -410,6 +456,20 @@ public class CollaborationSessionView extends SessionView implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if any drawing layer has been drawn on
|
||||
*/
|
||||
private boolean anyLayerHasDrawing() {
|
||||
boolean anyCanClear = false;
|
||||
for (DrawingToolLayer dtl : getAllLayers()) {
|
||||
if (dtl.hasDrawing()) {
|
||||
anyCanClear = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return anyCanClear;
|
||||
}
|
||||
|
||||
public void updateToolItems() {
|
||||
ToolBarManager mgr = (ToolBarManager) getViewSite().getActionBars()
|
||||
.getToolBarManager();
|
||||
|
@ -418,24 +478,21 @@ public class CollaborationSessionView extends SessionView implements
|
|||
mgr.insert(0, noEditorAction);
|
||||
}
|
||||
CollaborationDrawingResource currentResource = getCurrentDrawingResource();
|
||||
DrawingToolLayer layer = null;
|
||||
if (currentResource != null) {
|
||||
layer = currentResource.getDrawingLayerFor(currentResource
|
||||
.getMyUser());
|
||||
}
|
||||
DrawingToolLayer layer = getCurrentLayer();
|
||||
if (layer != null && currentResource.isSessionLeader()) {
|
||||
lockAction.getAction().setEnabled(true);
|
||||
clearAllAction.getAction().setEnabled(anyLayerHasDrawing());
|
||||
} else {
|
||||
lockAction.getAction().setEnabled(false);
|
||||
clearAllAction.getAction().setEnabled(false);
|
||||
}
|
||||
|
||||
// enable/disable toolbar buttons based on locked
|
||||
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());
|
||||
clearAction.getAction().setEnabled(layer.hasDrawing());
|
||||
eraseAction.getAction().setEnabled(true);
|
||||
switch (layer.getDrawMode()) {
|
||||
case DRAW:
|
||||
|
@ -539,7 +596,8 @@ public class CollaborationSessionView extends SessionView implements
|
|||
.getSelection();
|
||||
VenueParticipant entry = (VenueParticipant) selection
|
||||
.getFirstElement();
|
||||
if (!entry.isSameUser(session.getUserID())) {
|
||||
if (!entry.isSameUser(session.getUserID())
|
||||
&& session.isSharedDisplayClient(entry)) {
|
||||
manager.add(leaderChangeAction);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ 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.SiteConfigInformation;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.SharedDisplaySession;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.VenueParticipant;
|
||||
|
|
|
@ -42,7 +42,7 @@ 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.IPeerToPeer;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.session.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.connection.CollaborationConnection;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.RosterItem;
|
||||
import com.raytheon.uf.viz.collaboration.comm.provider.user.UserId;
|
||||
import com.raytheon.uf.viz.collaboration.ui.actions.PrintLogActionContributionItem;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue