Merge branch 'omaha_16.1.1' of ssh://vlab.ncep.noaa.gov:29418/AWIPS2_Dev_Baseline into ncep_16.1.1
Former-commit-id: 84c11478b4f3c993dceba9c2a831fdca3a952509
This commit is contained in:
commit
9c69b10f87
59 changed files with 3948 additions and 293 deletions
7
cave/com.raytheon.uf.viz.alertview.logback/.classpath
Normal file
7
cave/com.raytheon.uf.viz.alertview.logback/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
cave/com.raytheon.uf.viz.alertview.logback/.project
Normal file
28
cave/com.raytheon.uf.viz.alertview.logback/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.alertview.logback</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,13 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: LogBack AlertView compatibility
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.alertview.logback
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Eclipse-RegisterBuddy: ch.qos.logback
|
||||
Require-Bundle: ch.qos.logback;bundle-version="1.1.2",
|
||||
com.raytheon.uf.viz.alertview;bundle-version="1.15.0"
|
||||
Import-Package: org.osgi.framework;version="1.7.0",
|
||||
org.osgi.util.tracker;version="1.5.1"
|
||||
Bundle-ActivationPolicy: lazy
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.logback;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.util.tracker.ServiceTracker;
|
||||
|
||||
import ch.qos.logback.classic.PatternLayout;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
import ch.qos.logback.core.AppenderBase;
|
||||
import ch.qos.logback.core.Layout;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
|
||||
/**
|
||||
*
|
||||
* An {@link Appender} that converts {@link ILoggingEvent}s to {@link Alert}s
|
||||
* and sends them to all registered {@link AlertDestination}s. The
|
||||
* {@link Appender} can be configured with a {@link Layout} to provide custom
|
||||
* details in the alert, if no layout is provided the default layout is just the
|
||||
* exception with a full stack trace.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 16, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertViewAppender extends AppenderBase<ILoggingEvent> {
|
||||
|
||||
protected Layout<ILoggingEvent> layout;
|
||||
|
||||
private transient ServiceTracker<AlertDestination, AlertDestination> destinationTracker;
|
||||
|
||||
@Override
|
||||
protected void append(ILoggingEvent event) {
|
||||
AlertDestination[] destinations =destinationTracker
|
||||
.getServices(new AlertDestination[0]);
|
||||
if(destinations == null || destinations.length == 0){
|
||||
return;
|
||||
}
|
||||
Alert alert = new LoggingEventAlert(layout, event);
|
||||
for (AlertDestination destination : destinations) {
|
||||
destination.handleAlert(alert);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
BundleContext context = FrameworkUtil.getBundle(getClass())
|
||||
.getBundleContext();
|
||||
destinationTracker = new ServiceTracker<>(context, AlertDestination.class,
|
||||
null);
|
||||
destinationTracker.open();
|
||||
if (layout == null) {
|
||||
PatternLayout patternLayout = new PatternLayout();
|
||||
patternLayout.setContext(this.context);
|
||||
patternLayout.setPattern("%ex");
|
||||
layout = patternLayout;
|
||||
}
|
||||
layout.start();
|
||||
super.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
layout.stop();
|
||||
destinationTracker.close();
|
||||
destinationTracker = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
if (super.isStarted()) {
|
||||
return destinationTracker != null;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void setLayout(Layout<ILoggingEvent> layout) {
|
||||
this.layout = layout;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.logback;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.Layout;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Wraps an {@link ILoggingEvent} in the {@link Alert} interface so it can be
|
||||
* added to the AlertView.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 16, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class LoggingEventAlert implements Alert {
|
||||
|
||||
private final Layout<ILoggingEvent> layout;
|
||||
|
||||
private final ILoggingEvent event;
|
||||
|
||||
public LoggingEventAlert(Layout<ILoggingEvent> layout, ILoggingEvent event) {
|
||||
this.layout = layout;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Date getTime() {
|
||||
return new Date(event.getTimeStamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Priority getPriority() {
|
||||
if (event.getLevel() == Level.ERROR) {
|
||||
return Priority.ERROR;
|
||||
} else if (event.getLevel() == Level.WARN) {
|
||||
return Priority.WARN;
|
||||
} else if (event.getLevel() == Level.INFO) {
|
||||
return Priority.INFO;
|
||||
} else {
|
||||
return Priority.DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOrigin() {
|
||||
return event.getLoggerName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return event.getFormattedMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails() {
|
||||
return layout.doLayout(event);
|
||||
}
|
||||
|
||||
}
|
7
cave/com.raytheon.uf.viz.alertview/.classpath
Normal file
7
cave/com.raytheon.uf.viz.alertview/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
cave/com.raytheon.uf.viz.alertview/.project
Normal file
28
cave/com.raytheon.uf.viz.alertview/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>com.raytheon.uf.viz.alertview</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
17
cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF
Normal file
17
cave/com.raytheon.uf.viz.alertview/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,17 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: AlertView
|
||||
Bundle-SymbolicName: com.raytheon.uf.viz.alertview;singleton:=true
|
||||
Bundle-Version: 1.15.0.qualifier
|
||||
Bundle-Vendor: RAYTHEON
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Export-Package: com.raytheon.uf.viz.alertview
|
||||
Require-Bundle: org.eclipse.ui;bundle-version="3.8.2",
|
||||
org.eclipse.core.runtime;bundle-version="3.8.0",
|
||||
org.eclipse.jface.text;bundle-version="3.8.2",
|
||||
org.eclipse.ui.console;bundle-version="3.5.100",
|
||||
org.slf4j;bundle-version="1.7.5"
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Bundle-ClassPath: com.raytheon.uf.viz.alertview.jar
|
||||
Service-Component: OSGI-INF/*.xml
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.ui.popup.AlertPopup" enabled="true" immediate="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.ui.popup.AlertPopup" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertDestination" />
|
||||
</service>
|
||||
</component>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.prefs.RCPPrefStore" enabled="true" immediate="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.prefs.RCPPrefStore" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertViewPrefStore" />
|
||||
</service>
|
||||
</component>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component name="com.raytheon.uf.viz.alertview.store.MemoryAlertStore" enabled="true" immediate="true" xmlns="http://www.osgi.org/xmlns/scr/v1.1.0">
|
||||
<implementation class="com.raytheon.uf.viz.alertview.store.MemoryAlertStore" />
|
||||
<service>
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertDestination" />
|
||||
<provide interface="com.raytheon.uf.viz.alertview.AlertStore" />
|
||||
</service>
|
||||
</component>
|
9
cave/com.raytheon.uf.viz.alertview/build.properties
Normal file
9
cave/com.raytheon.uf.viz.alertview/build.properties
Normal file
|
@ -0,0 +1,9 @@
|
|||
jars.compile.order = com.raytheon.uf.viz.alertview.jar
|
||||
source.com.raytheon.uf.viz.alertview.jar = src/
|
||||
output.com.raytheon.uf.viz.alertview.jar = bin/
|
||||
bin.includes = META-INF/,\
|
||||
OSGI-INF/,\
|
||||
icons/,\
|
||||
plugin.xml,\
|
||||
defaultPrefs/,\
|
||||
com.raytheon.uf.viz.alertview.jar
|
|
@ -0,0 +1,7 @@
|
|||
<popUpPreferences>
|
||||
<filter>error</filter>
|
||||
<duration>5</duration>
|
||||
<width>500</width>
|
||||
<height>50</height>
|
||||
<corner>LOWER_RIGHT</corner>
|
||||
</popUpPreferences>
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<styleList>
|
||||
<style>
|
||||
<filter>error</filter>
|
||||
<foregroundColor>#FF0000</foregroundColor>
|
||||
</style>
|
||||
</styleList>
|
|
@ -0,0 +1,16 @@
|
|||
<popUpPreferences>
|
||||
<activeFilter>warnPlus</activeFilter>
|
||||
<filterMenu>
|
||||
<filter>all</filter>
|
||||
<text>All</text>
|
||||
</filterMenu>
|
||||
<filterMenu>
|
||||
<filter>error</filter>
|
||||
<text>Only Errors</text>
|
||||
</filterMenu>
|
||||
<filterMenu>
|
||||
<filter>warnPlus</filter>
|
||||
<text>Errors and Warnings</text>
|
||||
</filterMenu>
|
||||
<alertsToLoad>1000</alertsToLoad>
|
||||
</popUpPreferences>
|
BIN
cave/com.raytheon.uf.viz.alertview/icons/alertView.png
Normal file
BIN
cave/com.raytheon.uf.viz.alertview/icons/alertView.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 427 B |
40
cave/com.raytheon.uf.viz.alertview/plugin.xml
Normal file
40
cave/com.raytheon.uf.viz.alertview/plugin.xml
Normal file
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.ui.views">
|
||||
<view
|
||||
allowMultiple="false"
|
||||
category="com.raytheon.viz.ui"
|
||||
class="com.raytheon.uf.viz.alertview.ui.view.AlertView"
|
||||
icon="icons/alertView.png"
|
||||
id="com.raytheon.uf.viz.alertview.ui.view.AlertView"
|
||||
name="Alert View"
|
||||
restorable="true"/>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.menus">
|
||||
<menuContribution
|
||||
locationURI="menu:CAVE?after=browsers">
|
||||
<command
|
||||
commandId="com.raytheon.uf.viz.alertview.openAlertView"
|
||||
label="Open AlertView"
|
||||
style="push">
|
||||
</command>
|
||||
</menuContribution>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.handlers">
|
||||
<handler
|
||||
class="com.raytheon.uf.viz.alertview.ui.view.OpenAlertViewHandler"
|
||||
commandId="com.raytheon.uf.viz.alertview.openAlertView">
|
||||
</handler>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.ui.commands">
|
||||
<command
|
||||
id="com.raytheon.uf.viz.alertview.openAlertView"
|
||||
name="Open AlertView">
|
||||
</command>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
|
||||
/**
|
||||
* The primary interface for items that should be displayed in {@link AlertView}
|
||||
* .
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface Alert {
|
||||
|
||||
public enum Priority {
|
||||
DEBUG, INFO, WARN, ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The time the event occured that generated this alert.
|
||||
*/
|
||||
public Date getTime();
|
||||
|
||||
/**
|
||||
* @return The importance of the alert.
|
||||
*/
|
||||
public Priority getPriority();
|
||||
|
||||
/**
|
||||
* @return An arbitrary string describing the origin of the Alert. This
|
||||
* should be a short word or phrase that can be used by the user to
|
||||
* take special action based on origins that are more or less
|
||||
* important for a specific user.
|
||||
*/
|
||||
public String getOrigin();
|
||||
|
||||
/**
|
||||
* @return A short summary of the alert.
|
||||
*/
|
||||
public String getMessage();
|
||||
|
||||
/**
|
||||
* @return A detailed description of the alert.
|
||||
*/
|
||||
public String getDetails();
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
/**
|
||||
*
|
||||
* An OSGi service interface for any service component that needs to know about
|
||||
* {@link Alert}s. Any component which wants to contribute new alerts should
|
||||
* broadcast the Alert to all registered {@link AlertDestination}s. Any
|
||||
* componenet that needs to know about new Alerts should implement this
|
||||
* interface and register as a service.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertDestination {
|
||||
|
||||
public void handleAlert(Alert alert);
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* An OSGi service interface that provides a way for the AlertView to load
|
||||
* {@link Alert}s that arrive while it is not open. At a minimum a store should
|
||||
* be accumulating new messages as they arrive. A store may want to provide
|
||||
* persistant storage so that old alerts can be viewed from a new cave.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertStore {
|
||||
|
||||
/**
|
||||
* @return All stored alerts.
|
||||
*/
|
||||
public List<Alert> getAlerts();
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* An OSGi service interface that supplies configuration information to
|
||||
* AlertView components.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertViewPrefStore {
|
||||
|
||||
public InputStream readConfigFile(String fileName) throws IOException;
|
||||
|
||||
public OutputStream writeConfigFile(String fileName) throws IOException;
|
||||
|
||||
public void addListener(AlertViewPrefListener listener);
|
||||
|
||||
public void removeListener(AlertViewPrefListener listener);
|
||||
|
||||
public static interface AlertViewPrefListener {
|
||||
|
||||
public void prefFileChanged(String fileName);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Interface for an object that filters {@link Alert}s. This is used throughout
|
||||
* alertview to ensure the user can see only alerts they are interested in.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public interface AlertFilter {
|
||||
|
||||
public boolean filter(Alert alert);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
* An {@link AlertFilter} that always returns true, or always returns false,
|
||||
* ignoring the {@link Alert} that is passed in. This is used to implement a
|
||||
* filter that either always accepts or always rejects Alerts.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ConstantFilter implements AlertFilter {
|
||||
|
||||
public final boolean result;
|
||||
|
||||
public ConstantFilter(boolean result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(Alert alert) {
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
|
||||
/**
|
||||
*
|
||||
* Provides a lookup mechanism for getting {@link AlertFilter}s using an id.
|
||||
* This is especially useful when a filter is stored in a preference file
|
||||
* because the id provides a convenient representation to store it and the
|
||||
* manager provides a reliable way to lookup filters.
|
||||
*
|
||||
* TODO the current implementation just uses a small set of hard-coded filters.
|
||||
* This should be implemented so that new filters can be added by other plugins
|
||||
* and possibly even allow user defined filters to do things like regex the
|
||||
* message.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class FilterManager {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(FilterManager.class);
|
||||
|
||||
public static final AlertFilter NONE = new ConstantFilter(false);
|
||||
|
||||
private final Map<String, AlertFilter> filters = new HashMap<>();
|
||||
|
||||
public FilterManager() {
|
||||
loadDefaultFilters();
|
||||
}
|
||||
|
||||
private void loadDefaultFilters() {
|
||||
filters.put("all", new ConstantFilter(true));
|
||||
filters.put("none", new ConstantFilter(false));
|
||||
for (Priority p : Priority.values()) {
|
||||
filters.put(p.name().toLowerCase(), new PriorityFilter(p));
|
||||
}
|
||||
filters.put("warnPlus", new MinPriorityFilter(Priority.WARN));
|
||||
filters.put("infoPlus", new MinPriorityFilter(Priority.INFO));
|
||||
}
|
||||
|
||||
public AlertFilter getFilter(String id) {
|
||||
AlertFilter filter = filters.get(id);
|
||||
if (filter == null) {
|
||||
logger.warn("AlertView FilterManager failed to find a filter with an id of "
|
||||
+ id);
|
||||
filter = NONE;
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
|
||||
/**
|
||||
* An {@link AlertFilter} that returns true for {@link Alert}s that have a
|
||||
* priority equal to or above a specified level.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MinPriorityFilter implements AlertFilter {
|
||||
|
||||
private final Priority priority;
|
||||
|
||||
public MinPriorityFilter(Priority priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(Alert alert) {
|
||||
return alert.getPriority().ordinal() >= priority.ordinal();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.filter;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.Alert.Priority;
|
||||
|
||||
/**
|
||||
* An {@link AlertFilter} that returns true for {@link Alert}s that have a
|
||||
* priority equal to a specified level.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class PriorityFilter implements AlertFilter {
|
||||
|
||||
private final Priority priority;
|
||||
|
||||
public PriorityFilter(Priority priority) {
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean filter(Alert alert) {
|
||||
return alert.getPriority() == priority;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
|
||||
/**
|
||||
* Contains the preferences that control how {@link AlertView} appears to the
|
||||
* user.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class AlertViewPreferences {
|
||||
|
||||
private final List<FilterMenu> DEFAULT_FILTERS = Arrays.asList(
|
||||
new FilterMenu("All", "all"),
|
||||
new FilterMenu("Only Errors", "error"), new FilterMenu(
|
||||
"Errors + Warnings", "warnPlus"));
|
||||
|
||||
private String activeFilter = "warnPlus";
|
||||
|
||||
private List<FilterMenu> filterMenu = new ArrayList<>(DEFAULT_FILTERS);
|
||||
|
||||
private int alertsToLoad = 1000;
|
||||
|
||||
public String getActiveFilter() {
|
||||
return activeFilter;
|
||||
}
|
||||
|
||||
public void setActiveFilter(String activeFilter) {
|
||||
this.activeFilter = activeFilter;
|
||||
}
|
||||
|
||||
public List<FilterMenu> getFilterMenu() {
|
||||
return filterMenu;
|
||||
}
|
||||
|
||||
public void setFilterMenu(List<FilterMenu> filterMenu) {
|
||||
this.filterMenu = filterMenu;
|
||||
}
|
||||
|
||||
public int getAlertsToLoad() {
|
||||
return alertsToLoad;
|
||||
}
|
||||
|
||||
public void setAlertsToLoad(int alertsToLoad) {
|
||||
this.alertsToLoad = alertsToLoad;
|
||||
}
|
||||
|
||||
public static class FilterMenu {
|
||||
|
||||
private String text;
|
||||
|
||||
private String filter;
|
||||
|
||||
public FilterMenu() {
|
||||
|
||||
}
|
||||
|
||||
public FilterMenu(String text, String filter) {
|
||||
this.text = text;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.ui.popup.AlertPopup;
|
||||
|
||||
/**
|
||||
* Contains the preferences that control how {@link AlertPopup} appears to the
|
||||
* user.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
public class PopUpPreferences {
|
||||
|
||||
public static enum PopUpCorner {
|
||||
UPPER_LEFT, UPPER_RIGHT, LOWER_LEFT, LOWER_RIGHT;
|
||||
}
|
||||
|
||||
private String filter = "warnPlus";
|
||||
|
||||
private int duration = 3;
|
||||
|
||||
private PopUpCorner corner = PopUpCorner.LOWER_RIGHT;
|
||||
|
||||
private int width = 500;
|
||||
|
||||
private int height = 50;
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
public void setDuration(int duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public PopUpCorner getCorner() {
|
||||
return corner;
|
||||
}
|
||||
|
||||
public void setCorner(PopUpCorner corner) {
|
||||
this.corner = corner;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import javax.xml.bind.DataBindingException;
|
||||
import javax.xml.bind.JAXB;
|
||||
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.Constants;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.InvalidSyntaxException;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore;
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore.AlertViewPrefListener;
|
||||
|
||||
/**
|
||||
*
|
||||
* Handles the serialization and service management of a preference file. This
|
||||
* class is designed to be a more friendly way to consume an
|
||||
* {@link AlertViewPrefStore} service. To load preferences using this class the
|
||||
* Preference class P should be JAXB serializable and must provide a no-arg
|
||||
* constructor that initializaes the preferences to a usable state. In cases
|
||||
* when loading the preferences from files fails the no-arg constructor will be
|
||||
* used to return a default preference object.
|
||||
*
|
||||
* This class listens to changes from the {@link AlertViewPrefStore} service and
|
||||
* notifies its own listeners of changes to the specified file. It also listens
|
||||
* to changes to the available AlertViewPrefStore services and when a better
|
||||
* service becomes available it will reload the preferences from the new service
|
||||
* and notify listeners. This is especially useful during startup if the
|
||||
* prefered AlertViewPrefStore starts after other components.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 16, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
* @param <P>
|
||||
*/
|
||||
public class PreferenceFile<P> {
|
||||
|
||||
private static final String FILTER = "(" + Constants.OBJECTCLASS + "="
|
||||
+ AlertViewPrefStore.class.getName() + ")";
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private final BundleContext context;
|
||||
|
||||
private final String fileName;
|
||||
|
||||
private final Class<P> type;
|
||||
|
||||
private final Listener<P> listener;
|
||||
|
||||
private final AlertViewPrefListener prefStoreListener = new AlertViewPrefListener() {
|
||||
|
||||
@Override
|
||||
public void prefFileChanged(String fileName) {
|
||||
if (fileName.equals(PreferenceFile.this.fileName)) {
|
||||
updatePreferences(loadFromStore());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final ServiceListener serviceListener = new ServiceListener() {
|
||||
|
||||
@Override
|
||||
public void serviceChanged(ServiceEvent event) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ServiceReference<AlertViewPrefStore> ref = (ServiceReference<AlertViewPrefStore>) event
|
||||
.getServiceReference();
|
||||
if (event.getType() == ServiceEvent.REGISTERED) {
|
||||
add(ref);
|
||||
} else if (event.getType() == ServiceEvent.UNREGISTERING) {
|
||||
remove(ref);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private ServiceReference<AlertViewPrefStore> serviceReference;
|
||||
|
||||
private AlertViewPrefStore prefStore;
|
||||
|
||||
private P preferences;
|
||||
|
||||
public PreferenceFile(String fileName, Class<P> type, Listener<P> listener) {
|
||||
this.fileName = fileName;
|
||||
this.type = type;
|
||||
this.listener = listener;
|
||||
context = FrameworkUtil.getBundle(getClass()).getBundleContext();
|
||||
try {
|
||||
context.addServiceListener(serviceListener, FILTER);
|
||||
} catch (InvalidSyntaxException e) {
|
||||
/*
|
||||
* The FILTER is statically defined and very simple syntax so it is
|
||||
* unlikely that this will ever happen.
|
||||
*/
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
this.preferences = updateServiceReference(context
|
||||
.getServiceReference(AlertViewPrefStore.class));
|
||||
}
|
||||
|
||||
public void close(){
|
||||
if(serviceReference != null){
|
||||
remove(serviceReference);
|
||||
}
|
||||
context.removeServiceListener(serviceListener);
|
||||
}
|
||||
|
||||
protected P updateServiceReference(
|
||||
ServiceReference<AlertViewPrefStore> serviceReference) {
|
||||
this.serviceReference = serviceReference;
|
||||
if (serviceReference != null) {
|
||||
return updatePrefStore(context.getService(serviceReference));
|
||||
} else {
|
||||
return updatePrefStore(null);
|
||||
}
|
||||
}
|
||||
|
||||
protected P updatePrefStore(AlertViewPrefStore prefStore) {
|
||||
this.prefStore = prefStore;
|
||||
if (prefStore != null) {
|
||||
prefStore.addListener(prefStoreListener);
|
||||
}
|
||||
return loadFromStore();
|
||||
}
|
||||
|
||||
protected P loadFromStore() {
|
||||
P preferences = null;
|
||||
if (prefStore != null) {
|
||||
try (InputStream in = prefStore.readConfigFile(fileName)) {
|
||||
if (in != null) {
|
||||
preferences = JAXB.unmarshal(in, type);
|
||||
}
|
||||
} catch (IOException | DataBindingException e) {
|
||||
logger.error("Unable to load {} from {}", type.getSimpleName(),
|
||||
fileName, e);
|
||||
}
|
||||
}
|
||||
if (preferences == null) {
|
||||
try {
|
||||
preferences = type.newInstance();
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
/*
|
||||
* Docs indicate you should have a public no arg constructor, if
|
||||
* there isn't one then you get RuntimeExceptions.
|
||||
*/
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return preferences;
|
||||
}
|
||||
|
||||
protected void updatePreferences(P preferences) {
|
||||
if (!this.preferences.equals(preferences)) {
|
||||
this.preferences = preferences;
|
||||
listener.update(preferences);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void add(ServiceReference<AlertViewPrefStore> ref) {
|
||||
if (serviceReference == null || ref.compareTo(serviceReference) > 0) {
|
||||
if (serviceReference != null) {
|
||||
prefStore.removeListener(prefStoreListener);
|
||||
context.ungetService(serviceReference);
|
||||
}
|
||||
updatePreferences(updateServiceReference(ref));
|
||||
}
|
||||
}
|
||||
|
||||
protected void remove(ServiceReference<AlertViewPrefStore> ref) {
|
||||
if (ref.equals(serviceReference)) {
|
||||
context.ungetService(serviceReference);
|
||||
prefStore.removeListener(prefStoreListener);
|
||||
updatePreferences(updateServiceReference(context
|
||||
.getServiceReference(AlertViewPrefStore.class)));
|
||||
}
|
||||
}
|
||||
|
||||
public P get() {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
public void write(P preferences) {
|
||||
if (prefStore != null) {
|
||||
try {
|
||||
JAXB.marshal(preferences,
|
||||
prefStore.writeConfigFile(fileName));
|
||||
} catch (IOException e) {
|
||||
logger.error("Unable to write {} to {}", type.getSimpleName(),
|
||||
fileName, e);
|
||||
}
|
||||
}
|
||||
updatePreferences(preferences);
|
||||
}
|
||||
|
||||
public static interface Listener<T> {
|
||||
|
||||
public void update(T t);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,120 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.prefs;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.AlertViewPrefStore;
|
||||
|
||||
/**
|
||||
*
|
||||
* A simple {@link AlertViewPrefStore} that stores preferences in the state area
|
||||
* that the Eclipse Runtime Platform provides for this bundle. When no user file
|
||||
* is available the default version of the file is loaded from within this
|
||||
* bundle.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class RCPPrefStore implements AlertViewPrefStore {
|
||||
|
||||
private final Bundle bundle;
|
||||
|
||||
private final IPath root = new Path("defaultPrefs");
|
||||
|
||||
private final Set<AlertViewPrefListener> listeners = new CopyOnWriteArraySet<>();
|
||||
|
||||
public RCPPrefStore() {
|
||||
this.bundle = FrameworkUtil.getBundle(getClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream readConfigFile(String fileName) throws IOException {
|
||||
IPath userPath = Platform.getStateLocation(bundle).append(fileName);
|
||||
File file = userPath.toFile();
|
||||
if (file.exists()) {
|
||||
return new FileInputStream(file);
|
||||
} else {
|
||||
return FileLocator.openStream(bundle, root.append(fileName), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream writeConfigFile(String fileName)
|
||||
throws FileNotFoundException {
|
||||
IPath userPath = Platform.getStateLocation(bundle).append(fileName);
|
||||
return new NotificationOutputStream(userPath.toFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(AlertViewPrefListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(AlertViewPrefListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
private class NotificationOutputStream extends FileOutputStream {
|
||||
|
||||
private final String fileName;
|
||||
|
||||
public NotificationOutputStream(File file) throws FileNotFoundException {
|
||||
super(file);
|
||||
this.fileName = file.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.close();
|
||||
for (AlertViewPrefListener listener : listeners) {
|
||||
listener.prefFileChanged(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.store;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.AlertStore;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* A simple {@link AlertStore} that retains all {@link Alert}s that arrive in
|
||||
* memory.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class MemoryAlertStore implements AlertStore, AlertDestination,
|
||||
PreferenceFile.Listener<AlertViewPreferences> {
|
||||
|
||||
private ConcurrentLinkedQueue<Alert> alerts = new ConcurrentLinkedQueue<>();
|
||||
|
||||
private final PreferenceFile<AlertViewPreferences> prefsFile;
|
||||
|
||||
private int retentionCount;
|
||||
|
||||
public MemoryAlertStore() {
|
||||
prefsFile = new PreferenceFile<>("alert_view.xml",
|
||||
AlertViewPreferences.class, this);
|
||||
retentionCount = prefsFile.get().getAlertsToLoad();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AlertViewPreferences preferences) {
|
||||
retentionCount = preferences.getAlertsToLoad();
|
||||
while (alerts.size() > retentionCount) {
|
||||
alerts.poll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This will get called automatically by declaritive services.
|
||||
*/
|
||||
public void deactivate() {
|
||||
prefsFile.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(Alert alert) {
|
||||
/* Trim too desired number of alerts */
|
||||
if (alerts.size() >= retentionCount) {
|
||||
alerts.poll();
|
||||
}
|
||||
alerts.offer(alert);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Alert> getAlerts() {
|
||||
return Arrays.asList(alerts.toArray(new Alert[0]));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.style;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Styles that apply to an {@link Alert}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertStyle {
|
||||
|
||||
private String filter;
|
||||
|
||||
private String backgroundColor;
|
||||
|
||||
private String foregroundColor;
|
||||
|
||||
private String fontName;
|
||||
|
||||
private String fontStyle;
|
||||
|
||||
private Integer fontSize;
|
||||
|
||||
public AlertStyle() {
|
||||
|
||||
}
|
||||
|
||||
public AlertStyle(AlertStyle other) {
|
||||
this.filter = other.filter;
|
||||
this.backgroundColor = other.backgroundColor;
|
||||
this.foregroundColor = other.foregroundColor;
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public String getBackgroundColor() {
|
||||
return backgroundColor;
|
||||
}
|
||||
|
||||
public void setBackgroundColor(String backgroundColor) {
|
||||
this.backgroundColor = backgroundColor;
|
||||
}
|
||||
|
||||
public String getForegroundColor() {
|
||||
return foregroundColor;
|
||||
}
|
||||
|
||||
public void setForegroundColor(String foregroundColor) {
|
||||
this.foregroundColor = foregroundColor;
|
||||
}
|
||||
|
||||
public String getFontName() {
|
||||
return fontName;
|
||||
}
|
||||
|
||||
public void setFontName(String fontName) {
|
||||
this.fontName = fontName;
|
||||
}
|
||||
|
||||
public String getFontStyle() {
|
||||
return fontStyle;
|
||||
}
|
||||
|
||||
public void setFontStyle(String fontStyle) {
|
||||
this.fontStyle = fontStyle;
|
||||
}
|
||||
|
||||
public Integer getFontSize() {
|
||||
return fontSize;
|
||||
}
|
||||
|
||||
public void setFontSize(Integer fontSize) {
|
||||
this.fontSize = fontSize;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.style;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* JAXB serializable list of {@link AlertStyle}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class StyleList {
|
||||
|
||||
@XmlElement(name = "style")
|
||||
private List<AlertStyle> styles = new ArrayList<>();
|
||||
|
||||
public StyleList() {
|
||||
}
|
||||
|
||||
public StyleList(List<AlertStyle> styles) {
|
||||
this.styles = styles;
|
||||
}
|
||||
|
||||
public List<AlertStyle> getStyles() {
|
||||
return styles;
|
||||
}
|
||||
|
||||
public void setStyles(List<AlertStyle> styles) {
|
||||
this.styles = styles;
|
||||
}
|
||||
|
||||
public void addStyle(AlertStyle style) {
|
||||
if (styles == null) {
|
||||
styles = new ArrayList<AlertStyle>();
|
||||
}
|
||||
styles.add(style);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.style;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Device;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.FontData;
|
||||
import org.eclipse.swt.graphics.RGB;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
* Converts {@link AlertStyle}s into SWT colors and fonts.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class StyleManager {
|
||||
|
||||
private static final String CONFIG_FILE_LOC = "alert_styles.xml";
|
||||
|
||||
private static final String REGULAR = "Regular";
|
||||
|
||||
private static final String BOLD = "Bold";
|
||||
|
||||
private static final String ITALIC = "Italic";
|
||||
|
||||
private static final String BOLD_ITALIC = BOLD + "-" + ITALIC;
|
||||
|
||||
private final FilterManager filterManager = new FilterManager();
|
||||
|
||||
private List<AlertStyle> styles = new ArrayList<AlertStyle>();
|
||||
|
||||
public StyleManager() {
|
||||
readConfig();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
private void readConfig() {
|
||||
PreferenceFile<StyleList> file = new PreferenceFile<>(CONFIG_FILE_LOC,
|
||||
StyleList.class,
|
||||
new PreferenceFile.Listener<StyleList>() {
|
||||
|
||||
@Override
|
||||
public void update(StyleList t) {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
styles = file.get().getStyles();
|
||||
}
|
||||
|
||||
public Color getForegroundColor(Device device, Alert alert) {
|
||||
for (AlertStyle style : styles) {
|
||||
if (style.getForegroundColor() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style
|
||||
.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
return parseColor(device, style.getForegroundColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Color getBackgroundColor(Device device, Alert alert) {
|
||||
for (AlertStyle style : styles) {
|
||||
if (style.getBackgroundColor() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style
|
||||
.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
return parseColor(device, style.getBackgroundColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Font getFont(Device device, Alert alert) {
|
||||
String name = null;
|
||||
Integer size = null;
|
||||
String fstyle = null;
|
||||
for (AlertStyle style : styles) {
|
||||
if (name == null && style.getFontName() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style
|
||||
.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
name = style.getFontName();
|
||||
}
|
||||
}
|
||||
if (size == null && style.getFontSize() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style
|
||||
.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
size = style.getFontSize();
|
||||
}
|
||||
}
|
||||
if (fstyle == null && style.getFontStyle() != null) {
|
||||
AlertFilter filter = filterManager.getFilter(style
|
||||
.getFilter());
|
||||
if (filter.filter(alert)) {
|
||||
fstyle = style.getFontStyle();
|
||||
}
|
||||
}
|
||||
if (name != null && size != null && fstyle != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return getFont(device, name, size, fstyle);
|
||||
}
|
||||
|
||||
public static Font getFont(Device device, AlertStyle style) {
|
||||
return getFont(device, style.getFontName(), style.getFontSize(),
|
||||
style.getFontStyle());
|
||||
}
|
||||
|
||||
public static Font getFont(Device device, String name, Integer size,
|
||||
String style) {
|
||||
Integer fstyle = parseFontStyle(style);
|
||||
if (name != null && size != null && fstyle != null) {
|
||||
return new Font(device, new FontData(name, size, fstyle));
|
||||
}
|
||||
if (name == null && size == null && fstyle == null) {
|
||||
return device.getSystemFont();
|
||||
}
|
||||
FontData systemFontData = device.getSystemFont().getFontData()[0];
|
||||
if (name == null) {
|
||||
name = systemFontData.getName();
|
||||
}
|
||||
if (size == null) {
|
||||
size = systemFontData.getHeight();
|
||||
}
|
||||
if (fstyle == null) {
|
||||
fstyle = systemFontData.getStyle();
|
||||
}
|
||||
return new Font(device, new FontData(name, size, fstyle));
|
||||
}
|
||||
|
||||
public static void setFont(AlertStyle style, FontData data) {
|
||||
style.setFontName(data.getName());
|
||||
style.setFontSize(data.getHeight());
|
||||
style.setFontStyle(formatFontStyle(data.getStyle()));
|
||||
}
|
||||
|
||||
private static Integer parseFontStyle(String style) {
|
||||
if (style == null) {
|
||||
return null;
|
||||
} else if (style.equalsIgnoreCase(REGULAR)) {
|
||||
return SWT.NORMAL;
|
||||
} else if (style.equalsIgnoreCase(BOLD)) {
|
||||
return SWT.BOLD;
|
||||
} else if (style.equals(ITALIC)) {
|
||||
return SWT.ITALIC;
|
||||
} else if (style.equals(BOLD_ITALIC)) {
|
||||
return SWT.BOLD | SWT.ITALIC;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String formatFontStyle(Integer style) {
|
||||
if (style == null) {
|
||||
return null;
|
||||
} else if ((style & SWT.BOLD) == SWT.BOLD
|
||||
&& (style & SWT.ITALIC) == SWT.ITALIC) {
|
||||
return BOLD_ITALIC;
|
||||
} else if ((style & SWT.BOLD) == SWT.BOLD) {
|
||||
return BOLD;
|
||||
} else if ((style & SWT.ITALIC) == SWT.ITALIC) {
|
||||
return ITALIC;
|
||||
} else if ((style & SWT.NORMAL) == SWT.NORMAL) {
|
||||
return REGULAR;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Color parseColor(Device device, String str) {
|
||||
if (str == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
int red = Integer.parseInt(str.substring(1, 3), 16);
|
||||
int green = Integer.parseInt(str.substring(3, 5), 16);
|
||||
int blue = Integer.parseInt(str.substring(5, 7), 16);
|
||||
return new Color(device, red, green, blue);
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String formatColor(RGB colorValue) {
|
||||
return String.format("#%02x%02x%02x", colorValue.red, colorValue.green,
|
||||
colorValue.blue);
|
||||
}
|
||||
|
||||
public List<AlertStyle> getStyles() {
|
||||
return styles;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,325 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.popup;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.graphics.Rectangle;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Event;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Listener;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.ui.IWindowListener;
|
||||
import org.eclipse.ui.IWorkbench;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PopUpPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
import com.raytheon.uf.viz.alertview.style.StyleManager;
|
||||
import com.raytheon.uf.viz.alertview.ui.view.AlertView;
|
||||
|
||||
/**
|
||||
*
|
||||
* An {@link AlertDestination} which displays {@link Alert}s in a small popup
|
||||
* window. The window only display for a few seconds(exact time is configurable)
|
||||
* and then disappears. If the user clicks the popup it will open the displayed
|
||||
* alert in the {@link AlertView}
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 17, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertPopup implements AlertDestination,
|
||||
PreferenceFile.Listener<PopUpPreferences> {
|
||||
|
||||
private final PopupAlertTask task = new PopupAlertTask();
|
||||
|
||||
private final PreferenceFile<PopUpPreferences> prefsFile;
|
||||
|
||||
protected final FilterManager filters = new FilterManager();
|
||||
|
||||
protected final StyleManager styles = new StyleManager();
|
||||
|
||||
protected PopUpPreferences prefs;
|
||||
|
||||
public AlertPopup() {
|
||||
prefsFile = new PreferenceFile<>("alert_popup.xml",
|
||||
PopUpPreferences.class,
|
||||
this);
|
||||
prefs = prefsFile.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(PopUpPreferences preferences) {
|
||||
prefs = preferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will get called automatically by declaritive services.
|
||||
*/
|
||||
public void deactivate() {
|
||||
prefsFile.close();
|
||||
styles.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(Alert alert) {
|
||||
if (filters.getFilter(prefs.getFilter()).filter(alert)) {
|
||||
task.update(alert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This task will run on the UI thread and is responsible for managing the
|
||||
* popup window. This should not be run directly but will schedule itself
|
||||
* when {@link #update(Alert)} or {@link #clear(Alert)} is called.
|
||||
*/
|
||||
private class PopupAlertTask implements Runnable {
|
||||
|
||||
private final Timer timer = new Timer("Remove Alert Popup");
|
||||
|
||||
private Shell shell;
|
||||
|
||||
private Label label;
|
||||
|
||||
/**
|
||||
* This is the alert that should be dispalyed, the most recent alert
|
||||
* passed to update which has not been passed to clear.
|
||||
*/
|
||||
private volatile Alert alert;
|
||||
|
||||
/**
|
||||
* This is the currently displayed alert, it should only be used from
|
||||
* the UI thread. If this task is waiting to be run on the UI thread
|
||||
* then this will not be the same as alert.
|
||||
*/
|
||||
private Alert displayedAlert;
|
||||
|
||||
/**
|
||||
* Update the popup window with the provided alert. If the window is not
|
||||
* currently open then a new popup window will be opened to display the
|
||||
* alert. If a popup window is already displayed then this alert will
|
||||
* replace any other alert in the popup window. This method schedules an
|
||||
* update on the UI thread but it does not block. If multiple calls to
|
||||
* {@link #update(Alert)} are made before the UI thread becomes
|
||||
* available then only the most recent Alert will be displayed.
|
||||
*/
|
||||
public synchronized void update(Alert alert) {
|
||||
this.alert = alert;
|
||||
Display.getDefault().asyncExec(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the popup if the provided alert is the most recent alert that
|
||||
* should be displayed. The alert is provided to make clear an atomic
|
||||
* operation. If another alert has been provided to
|
||||
* {@link #update(Alert)} since clear was called then it will be a no-op
|
||||
* because the more recent alert needs to be displayed.
|
||||
*/
|
||||
public synchronized void clear(Alert alert) {
|
||||
if (alert == this.alert) {
|
||||
this.alert = null;
|
||||
Display.getDefault().asyncExec(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void openInAlertView() {
|
||||
if (displayedAlert != null) {
|
||||
IWorkbench workbench = PlatformUI.getWorkbench();
|
||||
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
|
||||
if (workbench.isStarting()) {
|
||||
workbench
|
||||
.addWindowListener(new ShowAlertViewWindowListener(
|
||||
displayedAlert));
|
||||
} else if (window != null) {
|
||||
AlertView.show(window, displayedAlert);
|
||||
}
|
||||
clear(displayedAlert);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
this.displayedAlert = this.alert;
|
||||
if (displayedAlert != null && (shell == null || shell.isDisposed())) {
|
||||
shell = new Shell(Display.getDefault(), SWT.NO_FOCUS
|
||||
| SWT.NO_TRIM | SWT.ON_TOP);
|
||||
GridLayout layout = new GridLayout(1, false);
|
||||
layout.marginHeight = 0;
|
||||
layout.marginWidth = 0;
|
||||
shell.setLayout(layout);
|
||||
shell.setForeground(Display.getDefault().getSystemColor(
|
||||
SWT.COLOR_BLACK));
|
||||
shell.addListener(SWT.Dispose, new Listener() {
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
shell = null;
|
||||
}
|
||||
});
|
||||
|
||||
final Composite comp = new Composite(shell, SWT.BORDER);
|
||||
|
||||
layout = new GridLayout(1, false);
|
||||
layout.marginHeight = 0;
|
||||
layout.marginWidth = 0;
|
||||
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
comp.setLayout(layout);
|
||||
comp.setLayoutData(data);
|
||||
|
||||
label = new Label(comp, SWT.WRAP);
|
||||
data = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||
label.setLayoutData(data);
|
||||
label.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseUp(MouseEvent e) {
|
||||
openInAlertView();
|
||||
}
|
||||
|
||||
});
|
||||
shell.setSize(prefs.getWidth(), prefs.getHeight());
|
||||
|
||||
Rectangle clientArea = Display.getDefault().getMonitors()[0]
|
||||
.getClientArea();
|
||||
|
||||
int offset = 2;
|
||||
int startX = offset;
|
||||
int startY = offset;
|
||||
switch (prefs.getCorner()) {
|
||||
case UPPER_LEFT:
|
||||
startX = clientArea.x + offset;
|
||||
startY = clientArea.y + offset;
|
||||
break;
|
||||
case UPPER_RIGHT:
|
||||
startX = clientArea.x + clientArea.width
|
||||
- shell.getSize().x - offset;
|
||||
startY = clientArea.y + offset;
|
||||
break;
|
||||
case LOWER_LEFT:
|
||||
startX = clientArea.x + offset;
|
||||
startY = clientArea.y + clientArea.height
|
||||
- shell.getSize().y - offset;
|
||||
break;
|
||||
case LOWER_RIGHT:
|
||||
startX = clientArea.x + clientArea.width
|
||||
- shell.getSize().x - offset;
|
||||
startY = clientArea.y + clientArea.height
|
||||
- shell.getSize().y - offset;
|
||||
break;
|
||||
}
|
||||
|
||||
shell.setLocation(startX, startY);
|
||||
shell.setVisible(true);
|
||||
}
|
||||
if (displayedAlert == null) {
|
||||
if (shell != null && !shell.isDisposed()) {
|
||||
shell.dispose();
|
||||
}
|
||||
} else {
|
||||
Display display = shell.getDisplay();
|
||||
label.setBackground(styles.getBackgroundColor(display,
|
||||
displayedAlert));
|
||||
label.setForeground(styles.getForegroundColor(display,
|
||||
displayedAlert));
|
||||
label.setFont(styles.getFont(display, displayedAlert));
|
||||
label.setText(displayedAlert.getMessage());
|
||||
timer.schedule(new ClosePopupTask(displayedAlert),
|
||||
prefs.getDuration() * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This task is scheduled from the UI thread whenever an alert is displayed
|
||||
* in a popup. It will call clear after the popup has expired. It is never
|
||||
* canceled but instead it relies on the atomic nature of
|
||||
* {@link #clear(Alert)} to ensure that if another alert arrives it will not
|
||||
* close the popup.
|
||||
*/
|
||||
private class ClosePopupTask extends TimerTask {
|
||||
|
||||
private final Alert alert;
|
||||
|
||||
public ClosePopupTask(Alert alert) {
|
||||
this.alert = alert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
task.clear(alert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the user clicks on the alert popup while the workbench is starting
|
||||
* then this listener will be used to wait until the workbench window is
|
||||
* opened and then display the alert.
|
||||
*/
|
||||
private class ShowAlertViewWindowListener implements IWindowListener {
|
||||
|
||||
private final Alert alert;
|
||||
|
||||
public ShowAlertViewWindowListener(Alert alert) {
|
||||
this.alert = alert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowOpened(IWorkbenchWindow window) {
|
||||
AlertView.show(window, alert);
|
||||
window.getWorkbench().removeWindowListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated(IWorkbenchWindow window) {
|
||||
/* Unused method required by interface. */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosed(IWorkbenchWindow window) {
|
||||
/* Unused method required by interface. */
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowActivated(IWorkbenchWindow window) {
|
||||
/* Unused method required by interface. */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.swt.custom.StyledText;
|
||||
import org.eclipse.swt.events.MenuAdapter;
|
||||
import org.eclipse.swt.events.MenuEvent;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.MenuItem;
|
||||
import org.eclipse.ui.console.ConsolePlugin;
|
||||
import org.eclipse.ui.console.IHyperlink;
|
||||
import org.eclipse.ui.console.IOConsole;
|
||||
import org.eclipse.ui.console.IOConsoleOutputStream;
|
||||
import org.eclipse.ui.console.TextConsoleViewer;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
|
||||
/**
|
||||
*
|
||||
* Used for viewing the details of {@link Alert}s. Since most alerts are
|
||||
* generated from logged errors this console is created so that links appear in
|
||||
* stack traces when the view is used in eclipse.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertConsoleViewer extends TextConsoleViewer {
|
||||
|
||||
private AlertConsole console;
|
||||
|
||||
private Alert alert;
|
||||
|
||||
public AlertConsoleViewer(Composite parent) {
|
||||
this(parent, new AlertConsole());
|
||||
}
|
||||
|
||||
private AlertConsoleViewer(Composite parent, AlertConsole console) {
|
||||
super(parent, console);
|
||||
this.console = console;
|
||||
console.setViewer(this);
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
StyledText text = getTextWidget();
|
||||
text.setEditable(false);
|
||||
Menu menu = new Menu(text);
|
||||
text.setMenu(menu);
|
||||
menu.addMenuListener(new MenuAdapter() {
|
||||
|
||||
@Override
|
||||
public void menuShown(MenuEvent e) {
|
||||
populateContextMenu(getTextWidget().getMenu());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected void populateContextMenu(Menu menu) {
|
||||
for (MenuItem item : menu.getItems()) {
|
||||
item.dispose();
|
||||
}
|
||||
if (alert == null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void setAlert(Alert alert) {
|
||||
if (this.alert == alert) {
|
||||
return;
|
||||
}
|
||||
this.alert = alert;
|
||||
console.clearConsole();
|
||||
if (alert == null) {
|
||||
return;
|
||||
}
|
||||
String details = alert.getDetails();
|
||||
if (details.isEmpty()) {
|
||||
details = alert.getMessage();
|
||||
}
|
||||
IOConsoleOutputStream os = console.newOutputStream();
|
||||
try {
|
||||
os.write(details);
|
||||
os.close();
|
||||
} catch (IOException e) {
|
||||
// TODO this.
|
||||
}
|
||||
}
|
||||
|
||||
protected void redraw() {
|
||||
Display.getDefault().syncExec(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
getTextWidget().redraw();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static class AlertConsole extends IOConsole {
|
||||
|
||||
private AlertConsoleViewer viewer;
|
||||
|
||||
public AlertConsole() {
|
||||
super("AlertViewConsole", "javaStackTraceConsole", null);
|
||||
ConsolePlugin.getDefault().getConsoleManager()
|
||||
.createPatternMatchListeners(this);
|
||||
}
|
||||
|
||||
public void setViewer(AlertConsoleViewer viewer) {
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addHyperlink(IHyperlink hyperlink, int offset, int length)
|
||||
throws BadLocationException {
|
||||
super.addHyperlink(hyperlink, offset, length);
|
||||
viewer.redraw();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,419 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.MenuAdapter;
|
||||
import org.eclipse.swt.events.MenuEvent;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.MouseMoveListener;
|
||||
import org.eclipse.swt.events.MouseTrackAdapter;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
import org.eclipse.swt.layout.FillLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Menu;
|
||||
import org.eclipse.swt.widgets.Table;
|
||||
import org.eclipse.swt.widgets.TableColumn;
|
||||
import org.eclipse.swt.widgets.TableItem;
|
||||
import org.eclipse.ui.progress.UIJob;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.style.StyleManager;
|
||||
|
||||
/**
|
||||
*
|
||||
* Table that displays {@link Alert}s.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertTable extends Composite {
|
||||
|
||||
public static final String COLUMN_TIME = "Time";
|
||||
|
||||
public static final String COLUMN_PRIORITY = "Priority";
|
||||
|
||||
public static final String COLUMN_ORIGIN = "Origin";
|
||||
|
||||
public static final String COLUMN_MESSAGE = "Message";
|
||||
|
||||
private Table alertTable;
|
||||
|
||||
private AlertFilter filter;
|
||||
|
||||
private BlockingQueue<Alert> alertsToAdd = new LinkedBlockingQueue<Alert>();
|
||||
|
||||
private StyleManager styles = new StyleManager();
|
||||
|
||||
/**
|
||||
* When things are going terribly wrong and a gazillion alerts are coming in
|
||||
* the UI will freeze if they aren't throttled a bit. This job tries to be
|
||||
* reasonablish about how much CPU to suck updating the table.
|
||||
*/
|
||||
private Job addAlertJob = new UIJob("Updating AlertView") {
|
||||
|
||||
@Override
|
||||
public IStatus runInUIThread(IProgressMonitor monitor) {
|
||||
Alert next = alertsToAdd.poll();
|
||||
if (next != null) {
|
||||
int processed = 0;
|
||||
while (next != null) {
|
||||
addAlertInternal(next);
|
||||
if (processed++ > 500) {
|
||||
this.schedule(100);
|
||||
break;
|
||||
}
|
||||
next = alertsToAdd.poll();
|
||||
}
|
||||
packColumns();
|
||||
}
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
};
|
||||
|
||||
public AlertTable(Composite parent) {
|
||||
super(parent, SWT.NONE);
|
||||
this.setLayout(new FillLayout());
|
||||
createAlertTable();
|
||||
}
|
||||
|
||||
protected void createAlertTable() {
|
||||
alertTable = new Table(this, SWT.H_SCROLL | SWT.V_SCROLL
|
||||
| SWT.FULL_SELECTION | SWT.MULTI);
|
||||
alertTable.setHeaderVisible(true);
|
||||
alertTable.setLinesVisible(true);
|
||||
rebuildColums();
|
||||
alertTable.addSelectionListener(new SelectionAdapter() {
|
||||
|
||||
@Override
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
alertSelected();
|
||||
}
|
||||
|
||||
});
|
||||
alertTable.addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseDoubleClick(MouseEvent e) {
|
||||
alertDoubleClick();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
alertTable.addMouseMoveListener(new MouseMoveListener() {
|
||||
|
||||
@Override
|
||||
public void mouseMove(MouseEvent e) {
|
||||
alertTable.setToolTipText(null);
|
||||
}
|
||||
});
|
||||
|
||||
alertTable.addMouseTrackListener(new MouseTrackAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseHover(MouseEvent e) {
|
||||
TableItem item = alertTable.getItem(new Point(e.x, e.y));
|
||||
if (item == null) {
|
||||
alertTable.setToolTipText(null);
|
||||
} else {
|
||||
Alert alert = getAlert(item);
|
||||
alertTable.setToolTipText(getToolTip(alert));
|
||||
}
|
||||
}
|
||||
});
|
||||
Menu menu = new Menu(alertTable);
|
||||
alertTable.setMenu(menu);
|
||||
menu.addMenuListener(new MenuAdapter() {
|
||||
|
||||
@Override
|
||||
public void menuShown(MenuEvent e) {
|
||||
populateContextMenu(alertTable.getMenu());
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void addAlert(Alert alert) {
|
||||
alertsToAdd.add(alert);
|
||||
addAlertJob.schedule();
|
||||
}
|
||||
|
||||
protected TableItem addAlertInternal(Alert alert) {
|
||||
if (filter != null && !filter.filter(alert)) {
|
||||
return null;
|
||||
}
|
||||
TableItem item = new TableItem(alertTable, SWT.NONE);
|
||||
item.setData(new ArrayList<Alert>(Arrays.asList(alert)));
|
||||
item.setText(getText(alert));
|
||||
applyStyle(item);
|
||||
alertTable.showItem(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
protected void applyStyle(TableItem item) {
|
||||
Alert alert = getAlert(item);
|
||||
item.setBackground(styles.getBackgroundColor(item.getDisplay(), alert));
|
||||
item.setForeground(styles.getForegroundColor(item.getDisplay(), alert));
|
||||
item.setFont(styles.getFont(item.getDisplay(), alert));
|
||||
}
|
||||
|
||||
public void setFilter(AlertFilter filter) {
|
||||
this.filter = filter;
|
||||
for (TableItem item : alertTable.getSelection()) {
|
||||
Alert alert = getAlert(item);
|
||||
if (!filter.filter(alert)) {
|
||||
item.dispose();
|
||||
}
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
Alert alert = getAlert(item);
|
||||
if (!filter.filter(alert)) {
|
||||
item.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh(Alert alert) {
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
List<Alert> alerts = getAlerts(item);
|
||||
if (alerts.contains(alert)) {
|
||||
boolean selected = false;
|
||||
alerts.remove(alert);
|
||||
if (alerts.isEmpty()) {
|
||||
selected = alertTable.isSelected(alertTable.indexOf(item));
|
||||
item.dispose();
|
||||
}
|
||||
TableItem newItem = addAlertInternal(alert);
|
||||
if (selected && newItem != null) {
|
||||
alertTable.select(alertTable.indexOf(newItem));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void select(Alert alert) {
|
||||
if (alertsToAdd.contains(alert)) {
|
||||
TableItem item = addAlertInternal(alert);
|
||||
alertTable.setSelection(alertTable.indexOf(item));
|
||||
alertSelected();
|
||||
return;
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
List<Alert> alerts = getAlerts(item);
|
||||
if (alerts.contains(alert)) {
|
||||
alertTable.setSelection(alertTable.indexOf(item));
|
||||
alertSelected();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void packColumns() {
|
||||
for (TableColumn column : alertTable.getColumns()) {
|
||||
column.pack();
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] getText(Alert alert) {
|
||||
TableColumn[] columns = alertTable.getColumns();
|
||||
String[] text = new String[columns.length];
|
||||
for (int i = 0; i < columns.length; i += 1) {
|
||||
if (columns[i].getText().equals(COLUMN_MESSAGE)) {
|
||||
text[i] = alert.getMessage().split("\n")[0];
|
||||
} else if (columns[i].getText().equals(COLUMN_TIME)) {
|
||||
text[i] = new SimpleDateFormat("hh:mm a").format(alert
|
||||
.getTime());
|
||||
} else if (columns[i].getText().equals(COLUMN_PRIORITY)) {
|
||||
text[i] = alert.getPriority().toString();
|
||||
} else if (columns[i].getText().equals(COLUMN_ORIGIN)) {
|
||||
text[i] = alert.getOrigin();
|
||||
} else {
|
||||
text[i] = "Unknown Field";
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
// public void setFilter(StatusMessageFilter filter) {
|
||||
// this.filter = filter;
|
||||
// for (TableItem item : alertTable.getSelection()) {
|
||||
// StatusMessage message = getStatusMessage(item);
|
||||
// if (!filter.filter(message)) {
|
||||
// item.dispose();
|
||||
// }
|
||||
// }
|
||||
// for (TableItem item : alertTable.getItems()) {
|
||||
// StatusMessage message = getStatusMessage(item);
|
||||
// if (!filter.filter(message)) {
|
||||
// item.dispose();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public void rebuildColums() {
|
||||
for (TableColumn column : alertTable.getColumns()) {
|
||||
column.dispose();
|
||||
}
|
||||
// TODO columns from config.
|
||||
for (String columnText : new String[] { COLUMN_TIME, COLUMN_PRIORITY,
|
||||
COLUMN_MESSAGE }) {
|
||||
TableColumn column = new TableColumn(alertTable, SWT.NONE);
|
||||
column.setText(columnText);
|
||||
}
|
||||
for (TableItem item : alertTable.getItems()) {
|
||||
item.setText(getText(getAlert(item)));
|
||||
}
|
||||
for (TableColumn column : alertTable.getColumns()) {
|
||||
column.pack();
|
||||
}
|
||||
}
|
||||
|
||||
protected String getToolTip(Alert alert) {
|
||||
StringBuilder toolTip = new StringBuilder();
|
||||
if (alert.getTime() != null) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(
|
||||
"yyyy-MM-dd_HH:mm:ss.SSS");
|
||||
toolTip.append("Time: ").append(sdf.format(alert.getTime()))
|
||||
.append("\n");
|
||||
}
|
||||
if (alert.getPriority() != null) {
|
||||
toolTip.append("Priority: ").append(alert.getPriority())
|
||||
.append("\n");
|
||||
}
|
||||
if (toolTip.charAt(toolTip.length() - 1) == '\n') {
|
||||
toolTip.deleteCharAt(toolTip.length() - 1);
|
||||
}
|
||||
return toolTip.toString();
|
||||
}
|
||||
|
||||
protected void populateContextMenu(Menu menu) {
|
||||
// TODO need standard way of filling menu with items.
|
||||
// for (MenuItem item : menu.getItems()) {
|
||||
// item.dispose();
|
||||
// }
|
||||
// List<StatusMessage> messages = getMultiSelection();
|
||||
// if (!messages.isEmpty()) {
|
||||
// manager.getMenuManager().populateContextMenu(menu, messages);
|
||||
// }
|
||||
// AcknowledgedFilter ackFilter = new AcknowledgedFilter();
|
||||
// boolean ackAll = false;
|
||||
// for (TableItem item : alertTable.getItems()) {
|
||||
// StatusMessage m = getStatusMessage(item);
|
||||
// if (ackFilter.filter(m) == false) {
|
||||
// ackAll = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (ackAll) {
|
||||
// new MenuItem(menu, SWT.SEPARATOR);
|
||||
// MenuItem item = new MenuItem(menu, SWT.NONE);
|
||||
// item.setText("Acknowledge All");
|
||||
// item.addSelectionListener(new SelectionAdapter() {
|
||||
//
|
||||
// @Override
|
||||
// public void widgetSelected(SelectionEvent e) {
|
||||
// AcknowledgedFilter filter = new AcknowledgedFilter();
|
||||
// AcknowledgeAction action = new AcknowledgeAction();
|
||||
// for (TableItem item : alertTable.getItems()) {
|
||||
// for (StatusMessage m : getStatusMessages(item)) {
|
||||
// if (filter.filter(m) == false) {
|
||||
// action.handle(m);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
public Alert getSingleSelection() {
|
||||
TableItem[] selection = alertTable.getSelection();
|
||||
if (selection == null || selection.length != 1) {
|
||||
return null;
|
||||
} else {
|
||||
return getAlert(selection[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Alert> getMultiSelection() {
|
||||
TableItem[] selection = alertTable.getSelection();
|
||||
if (selection == null || selection.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Alert> result = new ArrayList<Alert>();
|
||||
for (int i = 0; i < selection.length; i += 1) {
|
||||
result.addAll(getAlerts(selection[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public Alert getAlert(TableItem item) {
|
||||
return getAlerts(item).get(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Alert> getAlerts(TableItem item) {
|
||||
return (List<Alert>) item.getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
styles.close();
|
||||
}
|
||||
|
||||
protected void alertSelected() {
|
||||
// sub classes can override this easily
|
||||
}
|
||||
|
||||
protected void alertDoubleClick() {
|
||||
// sub classes can override this easily
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import org.eclipse.jface.action.Action;
|
||||
import org.eclipse.jface.action.IMenuManager;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.SashForm;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
import org.eclipse.ui.IViewPart;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.part.ViewPart;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.raytheon.uf.viz.alertview.Alert;
|
||||
import com.raytheon.uf.viz.alertview.AlertDestination;
|
||||
import com.raytheon.uf.viz.alertview.AlertStore;
|
||||
import com.raytheon.uf.viz.alertview.filter.AlertFilter;
|
||||
import com.raytheon.uf.viz.alertview.filter.FilterManager;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences;
|
||||
import com.raytheon.uf.viz.alertview.prefs.AlertViewPreferences.FilterMenu;
|
||||
import com.raytheon.uf.viz.alertview.prefs.PreferenceFile;
|
||||
|
||||
/**
|
||||
*
|
||||
* {@link IViewPart} for displaying {@link Alert}s. View is essentially just a
|
||||
* combination of an {@link AlertTable} and an {@link AlertConsoleViewer}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class AlertView extends ViewPart implements AlertDestination,
|
||||
PreferenceFile.Listener<AlertViewPreferences> {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(AlertView.class);
|
||||
|
||||
private ServiceRegistration<AlertDestination> destinationRegistration;
|
||||
|
||||
private SashForm sashForm;
|
||||
|
||||
private AlertTable alertTable;
|
||||
|
||||
private AlertConsoleViewer detailsConsoleViewer;
|
||||
|
||||
@Override
|
||||
public void createPartControl(Composite parent) {
|
||||
sashForm = new SashForm(parent, SWT.NONE);
|
||||
sashForm.setOrientation(SWT.VERTICAL);
|
||||
alertTable = new AlertTable(sashForm) {
|
||||
|
||||
@Override
|
||||
protected void alertSelected() {
|
||||
detailsConsoleViewer.setAlert(alertTable.getSingleSelection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void alertDoubleClick() {
|
||||
if (sashForm.getMaximizedControl() == alertTable) {
|
||||
sashForm.setMaximizedControl(null);
|
||||
} else {
|
||||
sashForm.setMaximizedControl(alertTable);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
detailsConsoleViewer = new AlertConsoleViewer(sashForm);
|
||||
|
||||
PreferenceFile<AlertViewPreferences> file = new PreferenceFile<>(
|
||||
"alert_view.xml", AlertViewPreferences.class, this);
|
||||
|
||||
/* TODO the menu button looks stupid in CAVE because of the small tabs. */
|
||||
IMenuManager menuManager = getViewSite().getActionBars()
|
||||
.getMenuManager();
|
||||
|
||||
FilterManager filterManager = new FilterManager();
|
||||
AlertViewPreferences prefs = file.get();
|
||||
for (FilterMenu filter : prefs.getFilterMenu()) {
|
||||
Action action = new ShowFilteredAction(filter.getText(),
|
||||
filterManager.getFilter(filter.getFilter()));
|
||||
if (prefs.getActiveFilter().equals(filter.getFilter())) {
|
||||
action.setChecked(true);
|
||||
action.run();
|
||||
}
|
||||
menuManager.add(action);
|
||||
}
|
||||
|
||||
sashForm.setMaximizedControl(alertTable);
|
||||
loadAlerts();
|
||||
}
|
||||
|
||||
private void loadAlerts() {
|
||||
BundleContext context = FrameworkUtil.getBundle(getClass())
|
||||
.getBundleContext();
|
||||
ServiceReference<AlertStore> ref = context
|
||||
.getServiceReference(AlertStore.class);
|
||||
if (ref != null) {
|
||||
AlertStore store = context.getService(ref);
|
||||
for (Alert alert : store.getAlerts()) {
|
||||
alertTable.addAlert(alert);
|
||||
}
|
||||
context.ungetService(ref);
|
||||
}
|
||||
destinationRegistration = context.registerService(
|
||||
AlertDestination.class, this, null);
|
||||
alertTable.packColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocus() {
|
||||
alertTable.setFocus();
|
||||
}
|
||||
|
||||
public void rebuildColums() {
|
||||
Display.getDefault().asyncExec(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
alertTable.rebuildColums();
|
||||
loadAlerts();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
destinationRegistration.unregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAlert(Alert alert) {
|
||||
alertTable.addAlert(alert);
|
||||
}
|
||||
|
||||
private class ShowFilteredAction extends Action {
|
||||
|
||||
private final AlertFilter filter;
|
||||
|
||||
public ShowFilteredAction(String name, AlertFilter filter) {
|
||||
super("Show " + name, Action.AS_RADIO_BUTTON);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
alertTable.setFilter(filter);
|
||||
detailsConsoleViewer.setAlert(alertTable.getSingleSelection());
|
||||
loadAlerts();
|
||||
// TODO save prefs.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void show(IWorkbenchWindow window, Alert alert) {
|
||||
IWorkbenchPage activePage = window.getActivePage();
|
||||
|
||||
try {
|
||||
AlertView view = (AlertView) activePage.showView(AlertView.class
|
||||
.getName());
|
||||
view.alertTable.select(alert);
|
||||
view.sashForm.setMaximizedControl(null);
|
||||
} catch (PartInitException e) {
|
||||
logger.error("Cannot open AlertView", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(AlertViewPreferences t) {
|
||||
// TODO update fitler menu.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.uf.viz.alertview.ui.view;
|
||||
|
||||
import org.eclipse.core.commands.AbstractHandler;
|
||||
import org.eclipse.core.commands.ExecutionEvent;
|
||||
import org.eclipse.core.commands.ExecutionException;
|
||||
import org.eclipse.core.commands.IHandler;
|
||||
import org.eclipse.ui.IWorkbenchPage;
|
||||
import org.eclipse.ui.IWorkbenchWindow;
|
||||
import org.eclipse.ui.PartInitException;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
/**
|
||||
*
|
||||
* {@link IHandler} that opens an {@link AlertView}.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------- -------- --------- --------------------------
|
||||
* Jun 18, 2015 4474 bsteffen Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class OpenAlertViewHandler extends AbstractHandler {
|
||||
|
||||
@Override
|
||||
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||
IWorkbenchWindow window = PlatformUI.getWorkbench()
|
||||
.getActiveWorkbenchWindow();
|
||||
if (window == null) {
|
||||
return null;
|
||||
}
|
||||
IWorkbenchPage activePage = window.getActivePage();
|
||||
try {
|
||||
activePage.showView(AlertView.class.getName());
|
||||
} catch (PartInitException e) {
|
||||
throw new ExecutionException("Error opening AlertView", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ import java.util.Map;
|
|||
import org.eclipse.jface.viewers.ColumnLabelProvider;
|
||||
import org.eclipse.jface.viewers.ILabelProviderListener;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.graphics.Color;
|
||||
import org.eclipse.swt.graphics.Font;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.swt.graphics.Point;
|
||||
|
@ -66,6 +67,7 @@ import com.raytheon.uf.viz.collaboration.ui.data.TreeObjectContainer;
|
|||
* Mar 06, 2014 2848 bclement get venueName directly from session
|
||||
* Jun 12, 2014 3267 bclement fixed missing null-check for outdated UI info
|
||||
* Oct 08, 2014 3705 bclement replaced checks for SessionGroupContainer with TreeObjectContainer
|
||||
* Jun 23, 2015 4563 mapeters bold/color users in contacts list if logged-in
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -86,6 +88,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
return connection.getContactsManager().getPresence(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayName(UserId user) {
|
||||
return getLocalAlias(user);
|
||||
}
|
||||
|
@ -136,7 +139,6 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
}
|
||||
return rval;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private List<ILabelProviderListener> listeners;
|
||||
|
@ -159,7 +161,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
if (element instanceof UserId) {
|
||||
return userLabelProvider.getImage(element);
|
||||
} else if (element instanceof RosterEntry) {
|
||||
return userLabelProvider.getImage((RosterEntry) element);
|
||||
return userLabelProvider.getImage(element);
|
||||
} else if (element instanceof RosterGroup) {
|
||||
key = "roster_group";
|
||||
} else if (element instanceof SharedGroup) {
|
||||
|
@ -168,7 +170,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
// key = "session_group";
|
||||
} else if (element instanceof TreeObjectContainer) {
|
||||
key = ((TreeObjectContainer) element).getIcon();
|
||||
}
|
||||
}
|
||||
|
||||
if (imageMap.get(key) == null && !key.equals("")) {
|
||||
imageMap.put(key, CollaborationUtils.getNodeImage(key));
|
||||
|
@ -183,7 +185,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
} else if (element instanceof SharedGroup) {
|
||||
return ((SharedGroup) element).getName();
|
||||
} else if (element instanceof RosterEntry) {
|
||||
return userLabelProvider.getText((RosterEntry) element);
|
||||
return userLabelProvider.getText(element);
|
||||
} else if (element instanceof TreeObjectContainer) {
|
||||
return ((TreeObjectContainer) element).getLabel();
|
||||
} else if (element instanceof UserId) {
|
||||
|
@ -211,10 +213,13 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
|
||||
@Override
|
||||
public Font getFont(Object element) {
|
||||
if (element instanceof RosterGroup || element instanceof SharedGroup
|
||||
|| element instanceof TreeObjectContainer) {
|
||||
// for this case do nothing, as it is not the top level of
|
||||
// session groups
|
||||
boolean isGroupTitle = element instanceof RosterGroup
|
||||
|| element instanceof SharedGroup
|
||||
|| element instanceof TreeObjectContainer;
|
||||
boolean isAvailableUser = element instanceof RosterEntry
|
||||
&& userLabelProvider.getPresence(
|
||||
userLabelProvider.convertObject(element)).isAvailable();
|
||||
if (isGroupTitle || isAvailableUser) {
|
||||
if (boldFont == null) {
|
||||
Font currFont = Display.getCurrent().getSystemFont();
|
||||
boldFont = new Font(Display.getCurrent(), currFont.toString(),
|
||||
|
@ -225,6 +230,17 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getForeground(Object element) {
|
||||
if (element instanceof RosterEntry) {
|
||||
UserId user = userLabelProvider.convertObject(element);
|
||||
if (userLabelProvider.getPresence(user).isAvailable()) {
|
||||
return Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tooltip text on the tree that this is a label provider for
|
||||
*/
|
||||
|
@ -234,7 +250,7 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
if (element instanceof UserId) {
|
||||
return userLabelProvider.getToolTipText(element);
|
||||
} else if (element instanceof RosterEntry) {
|
||||
return userLabelProvider.getToolTipText((RosterEntry) element);
|
||||
return userLabelProvider.getToolTipText(element);
|
||||
}
|
||||
// builds the tooltip text for the session group
|
||||
// portion of the view
|
||||
|
@ -242,10 +258,8 @@ public class UsersTreeLabelProvider extends ColumnLabelProvider {
|
|||
IVenueSession sessGroup = (IVenueSession) element;
|
||||
IVenue venue = sessGroup.getVenue();
|
||||
builder.append("ID: ").append(venue.getId());
|
||||
builder.append("\nName: ").append(venue.getName())
|
||||
.append("\n");
|
||||
builder.append("Subject: ").append(venue.getSubject())
|
||||
.append("\n");
|
||||
builder.append("\nName: ").append(venue.getName()).append("\n");
|
||||
builder.append("Subject: ").append(venue.getSubject()).append("\n");
|
||||
builder.append("Participants: ")
|
||||
.append(venue.getParticipantCount());
|
||||
return builder.toString();
|
||||
|
|
|
@ -19,14 +19,15 @@
|
|||
**/
|
||||
package com.raytheon.uf.viz.damagepath;
|
||||
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
|
||||
import javax.measure.converter.UnitConverter;
|
||||
import javax.measure.quantity.Length;
|
||||
import javax.measure.unit.NonSI;
|
||||
import javax.measure.unit.SI;
|
||||
import javax.measure.unit.Unit;
|
||||
|
||||
import org.geotools.referencing.GeodeticCalculator;
|
||||
|
||||
|
@ -35,51 +36,65 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
|
|||
import com.raytheon.uf.common.status.UFStatus;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.AbstractStormTrackResource;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState;
|
||||
import com.raytheon.viz.awipstools.common.stormtrack.StormTrackState.StormCoord;
|
||||
import com.raytheon.viz.radar.util.StationUtils;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
import com.vividsolutions.jts.geom.Geometry;
|
||||
import com.vividsolutions.jts.geom.GeometryFactory;
|
||||
import com.vividsolutions.jts.geom.Point;
|
||||
import com.vividsolutions.jts.geom.Polygon;
|
||||
|
||||
/**
|
||||
* Utility class for Damage Paths.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
* Mar 26, 2015 3977 nabowle Limit distance to avoid polar errors. Log
|
||||
* skipped points.
|
||||
* Apr 01, 2015 3977 nabowle rename the status handler.
|
||||
*
|
||||
* Jun 18, 2015 3977 nabowle Fix buffering. Renamed mehtods to
|
||||
* specify that they're for Tornados.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
public class DamagePathUtils {
|
||||
|
||||
/**
|
||||
* The number of degrees between points at the ends of a Tornado Damage Path
|
||||
* Buffer.
|
||||
*/
|
||||
private static final double END_DEGREE_DIFF = 30.0D;
|
||||
|
||||
private static final IUFStatusHandler statusHandler = UFStatus
|
||||
.getHandler(DamagePathUtils.class);
|
||||
|
||||
/** The unit for the uncertainty algorithm. */
|
||||
private static Unit<Length> TARGET_UNIT = NonSI.MILE;
|
||||
/** Convert miles for the algorithm to meters. */
|
||||
private static UnitConverter TO_METERS = NonSI.MILE
|
||||
.getConverterTo(SI.METER);
|
||||
|
||||
/** Convert meters returned the GeodeticCalculator to the desired unit. */
|
||||
private static UnitConverter METERS_TO = SI.METER
|
||||
.getConverterTo(TARGET_UNIT);
|
||||
/*
|
||||
* Pre-convert algorithm constants to meters to prevent having to convert
|
||||
* back and forth.
|
||||
*/
|
||||
private static final double ONE_TENTH_MILE = TO_METERS.convert(0.1);
|
||||
|
||||
private static final double THREE_TENTHS_MILE = TO_METERS.convert(0.3);
|
||||
|
||||
private static final double FORTY_MILES = TO_METERS.convert(40.0);
|
||||
|
||||
private static final double EIGHTY_MILES = TO_METERS.convert(80.0);
|
||||
|
||||
/**
|
||||
* Maximum distance of a point to the radar station to use when estimating a
|
||||
* damage path polygon. Any farther point will be ignored.
|
||||
* damage path polygon. Any farther point will be ignored. Based on radar
|
||||
* max extent
|
||||
*/
|
||||
private static final double MAX_DISTANCE = NonSI.MILE.getConverterTo(
|
||||
TARGET_UNIT).convert(300.0); // Based on radar max extent
|
||||
private static final double MAX_DISTANCE = TO_METERS.convert(300.0);
|
||||
|
||||
private DamagePathUtils() {
|
||||
super();
|
||||
|
@ -87,13 +102,13 @@ public class DamagePathUtils {
|
|||
|
||||
|
||||
/**
|
||||
* Estimates the damage path polygon for a storm track.
|
||||
* Estimates a Tornado damage path polygon for a storm track.
|
||||
*
|
||||
* @param stormTrack
|
||||
* The storm track to create a damage path for.
|
||||
* @return The estimated damage path polygon for a storm track.
|
||||
* The storm track to create a tornado damage path for.
|
||||
* @return The estimated tornado damage path polygon for a storm track.
|
||||
*/
|
||||
public static Polygon estimateDamagePath(
|
||||
public static Polygon estimateTornadoDamagePath(
|
||||
AbstractStormTrackResource stormTrack) {
|
||||
|
||||
StormTrackState stState = stormTrack.getStormTrackState();
|
||||
|
@ -102,10 +117,15 @@ public class DamagePathUtils {
|
|||
GeometryFactory gf = new GeometryFactory();
|
||||
|
||||
List<StormTrackState.StormCoord> skippedCoords = new ArrayList<>();
|
||||
Geometry damagePathBuffer = createBuffer(stState.timePoints, station,
|
||||
gf, null, skippedCoords);
|
||||
damagePathBuffer = createBuffer(stState.futurePoints, station, gf,
|
||||
damagePathBuffer, skippedCoords);
|
||||
List<Coordinate> validCoords = new ArrayList<>();
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
filterCoords(stState.timePoints, station, skippedCoords, validCoords,
|
||||
gc);
|
||||
filterCoords(stState.futurePoints, station, skippedCoords, validCoords,
|
||||
gc);
|
||||
|
||||
Coordinate[] damagePathCoords = createTornadoBuffer(validCoords, station, gc,
|
||||
gf);
|
||||
|
||||
if (!skippedCoords.isEmpty()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -123,7 +143,7 @@ public class DamagePathUtils {
|
|||
* user likely tried to import before creating track or entire track is
|
||||
* outside of the max range.
|
||||
*/
|
||||
if (damagePathBuffer == null) {
|
||||
if (damagePathCoords == null) {
|
||||
String suggestion;
|
||||
if (skippedCoords.isEmpty()) {
|
||||
suggestion = "Make sure the storm track is initialized.";
|
||||
|
@ -136,80 +156,195 @@ public class DamagePathUtils {
|
|||
return null;
|
||||
}
|
||||
|
||||
Polygon polygon = gf.createPolygon(damagePathBuffer.convexHull()
|
||||
.getCoordinates());
|
||||
Polygon polygon = gf.createPolygon(damagePathCoords);
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a buffers a buffer around the storm coordinates. If
|
||||
* damagePathBuffer is non null, the created buffer will be the union of the
|
||||
* two buffers.
|
||||
* Filter the coordinates based on their range to the given radar station.
|
||||
*
|
||||
* @param stormCoords
|
||||
* The storm track coordinates.
|
||||
* The coordinates.
|
||||
* @param station
|
||||
* The station to base distance on.
|
||||
* @param gf
|
||||
* The geometry factory.
|
||||
* @param damagePathBuffer
|
||||
* The current damage path buffer. May be null.
|
||||
* @param farCoords
|
||||
* The list to add any skipped coordinates to.
|
||||
* @return The created buffer. If damagePathBuffer is not null, the created
|
||||
* buffer will included damagePathBuffer.
|
||||
* The radar station.
|
||||
* @param skippedCoords
|
||||
* A list where coordinates that are out of range of the station
|
||||
* will be added to.
|
||||
* @param validCoords
|
||||
* A list where coordinates that are in range of the station will
|
||||
* be added to.
|
||||
* @param gc
|
||||
* A GeodeticCalculator.
|
||||
*/
|
||||
private static Geometry createBuffer(
|
||||
StormTrackState.StormCoord[] stormCoords, RadarStation station,
|
||||
GeometryFactory gf, Geometry damagePathBuffer,
|
||||
List<StormCoord> farCoords) {
|
||||
if (stormCoords == null || stormCoords.length == 0) {
|
||||
return damagePathBuffer;
|
||||
private static void filterCoords(StormTrackState.StormCoord[] stormCoords,
|
||||
RadarStation station,
|
||||
List<StormTrackState.StormCoord> skippedCoords,
|
||||
List<Coordinate> validCoords, GeodeticCalculator gc) {
|
||||
Coordinate stormCoord;
|
||||
double distance;
|
||||
if (stormCoords != null) {
|
||||
for (int i = 0; i < stormCoords.length; i++) {
|
||||
stormCoord = stormCoords[i].coord;
|
||||
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
|
||||
gc.setDestinationGeographicPoint(station.getLon(),
|
||||
station.getLat());
|
||||
distance = gc.getOrthodromicDistance();
|
||||
|
||||
if (distance > MAX_DISTANCE) {
|
||||
skippedCoords.add(stormCoords[i]);
|
||||
} else if (validCoords.isEmpty()
|
||||
|| !validCoords.get(validCoords.size() - 1).equals(
|
||||
stormCoords[i].coord)) {
|
||||
validCoords.add(stormCoords[i].coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a buffer around the line defined by the storm coordinates using
|
||||
* Doug Speheger's tornado damage path algorithm.
|
||||
*
|
||||
* @param stormCoords
|
||||
* The storm coordinates to create a damage path around.
|
||||
* @param station
|
||||
* The radar station to use.
|
||||
* @param gc
|
||||
* A GeodeticCalculator.
|
||||
* @param gf
|
||||
* A GeometryFactory.
|
||||
* @return A Geometry representing an estimated Tornado Damage Path for the
|
||||
* given storm coordinates. If the no coordinates are provided, null
|
||||
* is returned.
|
||||
*/
|
||||
private static Coordinate[] createTornadoBuffer(List<Coordinate> stormCoords,
|
||||
RadarStation station, GeodeticCalculator gc, GeometryFactory gf) {
|
||||
|
||||
if (stormCoords.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GeodeticCalculator gc = new GeodeticCalculator();
|
||||
Point point;
|
||||
Geometry buffer;
|
||||
double distanceMeters; // distance in meters
|
||||
double distance; // distance in the desired unit
|
||||
// left hand side points
|
||||
List<Point2D> lhsPoints = new ArrayList<>();
|
||||
// right hand side points
|
||||
Deque<Point2D> rhsPoints = new ArrayDeque<>();
|
||||
double distance;
|
||||
double uncertainty;
|
||||
double azimuth;
|
||||
double pointAzimuth;
|
||||
Coordinate stormCoord;
|
||||
for (int i = 0; i < stormCoords.length; i++) {
|
||||
stormCoord = stormCoords[i].coord;
|
||||
Coordinate otherCoord;
|
||||
/* Create a concave hull for a linear set of coordinates. */
|
||||
for (int i = 0; i < stormCoords.size(); i++) {
|
||||
stormCoord = stormCoords.get(i);
|
||||
gc.setStartingGeographicPoint(stormCoord.x, stormCoord.y);
|
||||
gc.setDestinationGeographicPoint(station.getLon(), station.getLat());
|
||||
distanceMeters = gc.getOrthodromicDistance();
|
||||
distance = METERS_TO.convert(distanceMeters);
|
||||
|
||||
if (distance > MAX_DISTANCE) {
|
||||
farCoords.add(stormCoords[i]);
|
||||
continue;
|
||||
}
|
||||
distance = gc.getOrthodromicDistance();
|
||||
|
||||
/*
|
||||
* Based off of research done by Doug Speheger comparing surveyed
|
||||
* tornado paths to manually identified radar tornadic vortex
|
||||
* signatures in 2008-2012. In the initial dataset, 87% of tornadoes
|
||||
* were within this range of uncertainty.
|
||||
*
|
||||
* Note: All units are in meters. Constants have been pre-converted
|
||||
* from miles to meters.
|
||||
*/
|
||||
if (distance < 40.0) {
|
||||
uncertainty = 0.3 + distance * 0.005;
|
||||
} else if (distance < 80.0) {
|
||||
uncertainty = 0.1 + distance * 0.01;
|
||||
if (distance < FORTY_MILES) {
|
||||
uncertainty = THREE_TENTHS_MILE + distance * 0.005;
|
||||
} else if (distance < EIGHTY_MILES) {
|
||||
uncertainty = ONE_TENTH_MILE + distance * 0.01;
|
||||
} else {
|
||||
uncertainty = distance * 0.015 - 0.3;
|
||||
uncertainty = distance * 0.015 - THREE_TENTHS_MILE;
|
||||
}
|
||||
|
||||
point = gf.createPoint(stormCoord);
|
||||
buffer = point.buffer(uncertainty);
|
||||
if (damagePathBuffer == null) {
|
||||
damagePathBuffer = buffer;
|
||||
if (stormCoords.size() == 1) {
|
||||
/*
|
||||
* In the case that there's only one coordinate, draw a circle
|
||||
* around the point and break out.
|
||||
*/
|
||||
for (double d = -180; d < 180; d += END_DEGREE_DIFF) {
|
||||
gc.setDirection(d, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < stormCoords.size() - 1) {
|
||||
otherCoord = stormCoords.get(i + 1);
|
||||
gc.setDestinationGeographicPoint(otherCoord.x, otherCoord.y);
|
||||
azimuth = gc.getAzimuth();
|
||||
|
||||
if (i == 0) {
|
||||
// create start cap
|
||||
pointAzimuth = clampAzimuth(azimuth + 90);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) {
|
||||
pointAzimuth = clampAzimuth(pointAzimuth
|
||||
+ END_DEGREE_DIFF);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Create two points at 90 degrees from the direction of the
|
||||
* path.
|
||||
*/
|
||||
pointAzimuth = clampAzimuth(azimuth - 90);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
lhsPoints.add(gc.getDestinationGeographicPoint());
|
||||
pointAzimuth = clampAzimuth(azimuth + 90);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
} else {
|
||||
damagePathBuffer = damagePathBuffer.union(buffer);
|
||||
// create end cap
|
||||
otherCoord = stormCoords.get(i - 1);
|
||||
gc.setDestinationGeographicPoint(otherCoord.x, otherCoord.y);
|
||||
azimuth = gc.getAzimuth();
|
||||
pointAzimuth = clampAzimuth(azimuth - 90);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
for (double d = END_DEGREE_DIFF; d <= 180; d += END_DEGREE_DIFF) {
|
||||
pointAzimuth = clampAzimuth(pointAzimuth - END_DEGREE_DIFF);
|
||||
gc.setDirection(pointAzimuth, uncertainty);
|
||||
rhsPoints.push(gc.getDestinationGeographicPoint());
|
||||
}
|
||||
}
|
||||
}
|
||||
return damagePathBuffer;
|
||||
lhsPoints.addAll(rhsPoints);
|
||||
|
||||
Coordinate[] coordinates = new Coordinate[lhsPoints.size() + 1];
|
||||
Point2D point;
|
||||
for (int i = 0; i < lhsPoints.size(); i++) {
|
||||
point = lhsPoints.get(i);
|
||||
coordinates[i] = new Coordinate(point.getX(), point.getY());
|
||||
}
|
||||
coordinates[coordinates.length - 1] = coordinates[0];
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamps the azimuth to [-180, 180]
|
||||
*
|
||||
* @param azimuth
|
||||
* The azimuth.
|
||||
* @return An equivalent azimuth in [-180, 180]
|
||||
*/
|
||||
private static double clampAzimuth(double azimuth) {
|
||||
double az = azimuth;
|
||||
while (az < -180.0) {
|
||||
az += 360.0;
|
||||
}
|
||||
|
||||
while (az > 180.0) {
|
||||
az -= 360.0;
|
||||
}
|
||||
|
||||
return az;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,21 +32,22 @@ import com.vividsolutions.jts.geom.Polygon;
|
|||
|
||||
/**
|
||||
* Action to create a damage path from a DistanceSpeedLayer.
|
||||
*
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Mar 23, 2015 3977 nabowle Initial creation
|
||||
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
|
||||
* Jun 01, 2015 3975 dgilling Update for DamageLayer changes for
|
||||
* multiple polygon support.
|
||||
* Jun 18, 2015 4354 dgilling Update isEnabled to consider editable
|
||||
* capability.
|
||||
*
|
||||
* Jun 19, 2015 3977 nabowle Specify Tornado Path.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
*
|
||||
* @author nabowle
|
||||
* @version 1.0
|
||||
*/
|
||||
|
@ -57,7 +58,7 @@ public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
|||
.getHandler(ImportFromDistanceSpeedAction.class);
|
||||
|
||||
public ImportFromDistanceSpeedAction() {
|
||||
super("New from Distance Speed Tool");
|
||||
super("New Tornado Path from Distance Speed Tool");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,7 +74,7 @@ public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
|||
return;
|
||||
}
|
||||
|
||||
Polygon polygon = DamagePathUtils.estimateDamagePath(dsLayer);
|
||||
Polygon polygon = DamagePathUtils.estimateTornadoDamagePath(dsLayer);
|
||||
|
||||
if (polygon != null) {
|
||||
layer.addPolygon(polygon.getExteriorRing().getCoordinates());
|
||||
|
@ -101,7 +102,7 @@ public class ImportFromDistanceSpeedAction extends AbstractRightClickAction {
|
|||
|
||||
/**
|
||||
* Finds the DistanceSpeedLayer.
|
||||
*
|
||||
*
|
||||
* @param rsc
|
||||
* The current resource
|
||||
* @return The found DistanceSpeedLayer, or null if the tool is not loaded.
|
||||
|
|
|
@ -2,5 +2,6 @@ output.com.raytheon.uf.viz.thinclient.cave.jar = bin/
|
|||
bin.includes = META-INF/,\
|
||||
plugin.xml,\
|
||||
ThinClientPluginBlacklist.txt,\
|
||||
com.raytheon.uf.viz.thinclient.cave.jar
|
||||
com.raytheon.uf.viz.thinclient.cave.jar,\
|
||||
logback-viz-thinclient.xml
|
||||
source.com.raytheon.uf.viz.thinclient.cave.jar = src/
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
<configuration debug="false" scan="true">
|
||||
<!-- Only define when not wanting to use the UF Standard.
|
||||
<property scope="context" name="log.message.pattern" value="%-5p %d [%t] %c{0}: %m%n"/>
|
||||
-->
|
||||
|
||||
<!-- this appender will send System.err and System.out to the console log -->
|
||||
<appender name="CaveConsoleAppender" class="com.raytheon.uf.common.logback.appender.EnvConfigSysStreamFileAppender">
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
<!-- set envLogVar after encoder to avoid warning -->
|
||||
<envLogVar>LOGFILE_CONSOLE</envLogVar>
|
||||
</appender>
|
||||
|
||||
<!-- TODO should somehow be contributed from alertview plugin -->
|
||||
<appender name="AlertViewAppender" class="com.raytheon.uf.viz.alertview.logback.AlertViewAppender" />
|
||||
|
||||
|
||||
<!-- these two appenders will allow System.out and System.err to print to the console when
|
||||
-noredirect flag is used at cave startup-->
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<target>System.out</target>
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
<!-- TODO does anyone know why there is an InvertedThresholdFilter here? -->
|
||||
<filter class="com.raytheon.uf.common.logback.filter.InvertedThresholdFilter">
|
||||
<level>INFO</level>
|
||||
</filter>
|
||||
</appender>
|
||||
<appender name="errConsole" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<target>System.err</target>
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>WARN</level>
|
||||
</filter>
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
</appender>
|
||||
|
||||
<!-- this appender will log the messages sent to UFStatus -->
|
||||
<appender name="CaveLogAppender" class="com.raytheon.uf.common.logback.appender.EnvConfigurableRollingFileAppender">
|
||||
<!-- file and fileNamePattern will be overridden by the env variable if present, but are required by logback -->
|
||||
<file>cave-logs.log</file>
|
||||
<envLogVar>LOGFILE_CAVE</envLogVar>
|
||||
<rollingPolicy class="com.raytheon.uf.common.logback.policy.EnvConfigurableFixedWindowRollingPolicy">
|
||||
<fileNamePattern>cave-logs.log%i</fileNamePattern>
|
||||
<envLogVar>LOGFILE_CAVE</envLogVar>
|
||||
<minIndex>1</minIndex>
|
||||
<maxIndex>5</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
</triggeringPolicy>
|
||||
<append>true</append>
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
</appender>
|
||||
|
||||
<appender name="PerformanceLogAppender" class="com.raytheon.uf.common.logback.appender.EnvConfigurableRollingFileAppender">
|
||||
<!-- file and fileNamePattern will be overridden by the env variable if present, but are required by logback -->
|
||||
<file>cave-performance.log</file>
|
||||
<envLogVar>LOGFILE_PERFORMANCE</envLogVar>
|
||||
<rollingPolicy class="com.raytheon.uf.common.logback.policy.EnvConfigurableFixedWindowRollingPolicy">
|
||||
<fileNamePattern>cave-performance.log%i</fileNamePattern>
|
||||
<envLogVar>LOGFILE_PERFORMANCE</envLogVar>
|
||||
<minIndex>1</minIndex>
|
||||
<maxIndex>5</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
</triggeringPolicy>
|
||||
<append>true</append>
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
</appender>
|
||||
|
||||
<!-- TODO should somehow be contributed from viz.gfe plugin -->
|
||||
<appender name="ProductEditorLogAppender" class="com.raytheon.uf.common.logback.appender.EnvConfigurableRollingFileAppender">
|
||||
<!-- file and fileNamePattern will be overridden by the env variable if present, but are required by logback -->
|
||||
<file>cave-producteditor.log</file>
|
||||
<envLogVar>LOGFILE_PRODUCT_EDITOR</envLogVar>
|
||||
<rollingPolicy class="com.raytheon.uf.common.logback.policy.EnvConfigurableFixedWindowRollingPolicy">
|
||||
<fileNamePattern>cave-producteditor.log%i</fileNamePattern>
|
||||
<envLogVar>LOGFILE_PRODUCT_EDITOR</envLogVar>
|
||||
<minIndex>1</minIndex>
|
||||
<maxIndex>5</maxIndex>
|
||||
</rollingPolicy>
|
||||
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
|
||||
<maxFileSize>2GB</maxFileSize>
|
||||
</triggeringPolicy>
|
||||
<append>true</append>
|
||||
<encoder class="com.raytheon.uf.common.logback.encoder.UFStdEncoder"/>
|
||||
</appender>
|
||||
|
||||
<appender name="AsyncCaveLogAppender" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<queueSize>500</queueSize>
|
||||
<appender-ref ref="CaveLogAppender"/>
|
||||
<appender-ref ref="AlertViewAppender"/>
|
||||
</appender>
|
||||
|
||||
<appender name="AsyncPerfLogAppender" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<queueSize>500</queueSize>
|
||||
<appender-ref ref="PerformanceLogAppender"/>
|
||||
</appender>
|
||||
|
||||
<appender name="AsyncProductEditorLogAppender" class="ch.qos.logback.classic.AsyncAppender">
|
||||
<queueSize>500</queueSize>
|
||||
<appender-ref ref="ProductEditorLogAppender"/>
|
||||
</appender>
|
||||
|
||||
<logger name="CaveLogger" additivity="false">
|
||||
<level value="ALL"/>
|
||||
<appender-ref ref="AsyncCaveLogAppender"/>
|
||||
</logger>
|
||||
|
||||
<logger name="PerformanceLogger" additivity="false">
|
||||
<level value="ALL"/>
|
||||
<appender-ref ref="AsyncPerfLogAppender"/>
|
||||
</logger>
|
||||
|
||||
<logger name="ProductEditorLogger" additivity="false">
|
||||
<level value="ALL"/>
|
||||
<appender-ref ref="AsyncProductEditorLogAppender"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.raytheon">
|
||||
<level value="INFO"/>
|
||||
</logger>
|
||||
|
||||
<logger name="mx4j">
|
||||
<level value="ERROR"/>
|
||||
</logger>
|
||||
<logger name="org.apache">
|
||||
<level value="INFO"/>
|
||||
</logger>
|
||||
<logger name="org.apache.commons.beanutils">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.apache.qpid">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.geotools">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.apache.xbean.spring">
|
||||
<level value="WARN"/>
|
||||
</logger>
|
||||
<logger name="org.springframework">
|
||||
<level value="ERROR"/>
|
||||
</logger>
|
||||
<root>
|
||||
<level value="INFO"/>
|
||||
<appender-ref ref="console"/>
|
||||
<appender-ref ref="errConsole"/>
|
||||
<appender-ref ref="CaveConsoleAppender"/>
|
||||
</root>
|
||||
</configuration>
|
|
@ -23,6 +23,7 @@
|
|||
<import feature="com.raytheon.uf.viz.core.feature" version="1.0.0.qualifier"/>
|
||||
<import feature="com.raytheon.viz.text.feature" version="1.0.0.qualifier"/>
|
||||
<import feature="com.raytheon.uf.viz.kml.export.feature" version="1.0.0.qualifier"/>
|
||||
<import feature="com.raytheon.uf.viz.nwsauth.feature" version="1.0.0.qualifer"/>
|
||||
</requires>
|
||||
|
||||
<plugin
|
||||
|
|
|
@ -347,7 +347,8 @@ import com.raytheon.viz.ui.dialogs.SWTMessageBox;
|
|||
* 15Feb2015 4001 dgilling Ensure all fields are set in SendPracticeProductRequest.
|
||||
* 05Mar2015 RM 15025 kshrestha Fix to maintain the headers that they are saved with
|
||||
* 10Mar2015 RM 14866 kshrestha Disable QC GUI pop up for TextWS
|
||||
* 6Apr2015 RM14968 mgamazaychikov Fix formatting for pathcast section
|
||||
* 06Apr2015 RM14968 mgamazaychikov Fix formatting for pathcast section
|
||||
* 15Jun2015 4441 randerso Unconditionally convert text to upper case for QC
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -4909,8 +4910,7 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
if (warnGenFlag) {
|
||||
QCConfirmationMsg qcMsg = new QCConfirmationMsg();
|
||||
if (!qcMsg.checkWarningInfo(headerTF.getText().toUpperCase(),
|
||||
MixedCaseProductSupport.conditionalToUpper(prod.getNnnid(),
|
||||
textEditor.getText()), prod.getNnnid())) {
|
||||
textEditor.getText().toUpperCase(), prod.getNnnid())) {
|
||||
WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell,
|
||||
qcMsg.getTitle(), qcMsg.getProductMessage(),
|
||||
qcMsg.getModeMessage());
|
||||
|
@ -4964,11 +4964,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
return;
|
||||
}
|
||||
|
||||
if (isWarnGenDlg == true){
|
||||
if (isWarnGenDlg == true) {
|
||||
StdTextProduct prod = getStdTextProduct();
|
||||
String afosId = prod.getCccid() + prod.getNnnid() + prod.getXxxid();
|
||||
SendConfirmationMsg sendMsg = new SendConfirmationMsg(resend, afosId,
|
||||
prod.getNnnid());
|
||||
SendConfirmationMsg sendMsg = new SendConfirmationMsg(resend,
|
||||
afosId, prod.getNnnid());
|
||||
|
||||
WarnGenConfirmationDlg wgcd = new WarnGenConfirmationDlg(shell,
|
||||
sendMsg.getTitle(), sendMsg.getProductMessage(),
|
||||
|
@ -5748,140 +5748,154 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
int afosXxxLimit = 5; // second three characters is AFOS XXX
|
||||
String prodText = textEditor.getText();
|
||||
|
||||
if (!prodText.startsWith("ZCZC")) {
|
||||
/*
|
||||
* DR15610 - Make sure that if the first line of the text product is not
|
||||
* a WMO heading it is treated as part of the text body.
|
||||
*/
|
||||
String[] pieces = textEditor.getText().split("\r*\n", 2);
|
||||
if (pieces.length > 1) {
|
||||
pieces[0] += "\n"; // WMOHeader expects this
|
||||
}
|
||||
WMOHeader header = new WMOHeader(pieces[0].getBytes(), null);
|
||||
if (!header.isValid()) {
|
||||
headerTF.setText("");
|
||||
try {
|
||||
textEditor.setText(originalText);
|
||||
textEditor.setEditable(true);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty string.
|
||||
textEditor.setText("");
|
||||
if (!prodText.startsWith("ZCZC")) {
|
||||
/*
|
||||
* DR15610 - Make sure that if the first line of the text product is
|
||||
* not a WMO heading it is treated as part of the text body.
|
||||
*/
|
||||
String[] pieces = textEditor.getText().split("\r*\n", 2);
|
||||
if (pieces.length > 1) {
|
||||
pieces[0] += "\n"; // WMOHeader expects this
|
||||
}
|
||||
} else {
|
||||
// TODO FIX PARSING
|
||||
|
||||
// First, set the current header by assuming that it usually
|
||||
// consists of the first two lines of text in the text product,
|
||||
// though there will be exceptions to that "rule" as handled below.
|
||||
// So, obtain the AFOS NNNxxx. If it's where it is supposed to be
|
||||
// in the new format, then the existing header is already an AWIPS
|
||||
// text product identifier. Otherwise it is a legacy AFOS
|
||||
// identifier.
|
||||
if (TextDisplayModel.getInstance().hasStdTextProduct(token)) {
|
||||
StdTextProduct textProd = TextDisplayModel.getInstance()
|
||||
.getStdTextProduct(token);
|
||||
StdTextProductId prodId = textProd.getProdId();
|
||||
WMOHeader header = new WMOHeader(pieces[0].getBytes(), null);
|
||||
if (!header.isValid()) {
|
||||
headerTF.setText("");
|
||||
try {
|
||||
// start of second line of text
|
||||
start = textEditor.getOffsetAtLine(thisLine + 1);
|
||||
if ((textEditor.getText(start, start + afosNnnLimit)
|
||||
.equals(prodId.getNnnid()))
|
||||
&& (textEditor.getText(start + afosNnnLimit + 1,
|
||||
start + afosXxxLimit).equals(prodId
|
||||
.getXxxid()))) {
|
||||
// Text matches the products nnnid and xxxid
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else if (textEditor.getText(start,
|
||||
start + afosNnnLimit + 2).equals(
|
||||
AFOSParser.DRAFT_PIL)
|
||||
|| textEditor.getText(start,
|
||||
start + afosNnnLimit + 2).equals("TTAA0")) {
|
||||
// Text matches temporary WRKWG#
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else {
|
||||
textEditor.setText(originalText);
|
||||
textEditor.setEditable(true);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty
|
||||
// string.
|
||||
textEditor.setText("");
|
||||
}
|
||||
} else {
|
||||
// TODO FIX PARSING
|
||||
|
||||
// First, set the current header by assuming that it usually
|
||||
// consists of the first two lines of text in the text product,
|
||||
// though there will be exceptions to that "rule" as handled
|
||||
// below.
|
||||
// So, obtain the AFOS NNNxxx. If it's where it is supposed to
|
||||
// be
|
||||
// in the new format, then the existing header is already an
|
||||
// AWIPS
|
||||
// text product identifier. Otherwise it is a legacy AFOS
|
||||
// identifier.
|
||||
if (TextDisplayModel.getInstance().hasStdTextProduct(token)) {
|
||||
StdTextProduct textProd = TextDisplayModel.getInstance()
|
||||
.getStdTextProduct(token);
|
||||
StdTextProductId prodId = textProd.getProdId();
|
||||
try {
|
||||
// start of second line of text
|
||||
start = textEditor.getOffsetAtLine(thisLine + 1);
|
||||
if ((textEditor.getText(start, start + afosNnnLimit)
|
||||
.equals(prodId.getNnnid()))
|
||||
&& (textEditor.getText(
|
||||
start + afosNnnLimit + 1, start
|
||||
+ afosXxxLimit).equals(prodId
|
||||
.getXxxid()))) {
|
||||
// Text matches the products nnnid and xxxid
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else if (textEditor.getText(start,
|
||||
start + afosNnnLimit + 2).equals(
|
||||
AFOSParser.DRAFT_PIL)
|
||||
|| textEditor.getText(start,
|
||||
start + afosNnnLimit + 2).equals(
|
||||
"TTAA0")) {
|
||||
// Text matches temporary WRKWG#
|
||||
numberOfLinesOfHeaderText = 2;
|
||||
} else {
|
||||
// Assume this header block is a legacy AFOS
|
||||
// identifier.
|
||||
numberOfLinesOfHeaderText = 1;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Assume this header block is a legacy AFOS identifier.
|
||||
numberOfLinesOfHeaderText = 1;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
start = 0;
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText) - 1;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// Assume this header block is a legacy AFOS identifier.
|
||||
numberOfLinesOfHeaderText = 1;
|
||||
// The text does not span enough lines so use the full
|
||||
// extent
|
||||
// of the product.
|
||||
finish = textEditor.getCharCount() - 1;
|
||||
}
|
||||
|
||||
// Set the content of the header block to consist of just the
|
||||
// header
|
||||
// of
|
||||
// the text product... it will get reunited with the body when
|
||||
// it is
|
||||
// saved.
|
||||
if (finish > start) {
|
||||
headerTF.setText(textEditor.getText(start, finish));
|
||||
} else {
|
||||
headerTF.setText("");
|
||||
}
|
||||
|
||||
// Next, set the current body by assuming that it always
|
||||
// consists of the rest of the text product beyond the line(s)
|
||||
// of text in the header.
|
||||
try {
|
||||
int numberOfBlankLines = -1;
|
||||
String line = null;
|
||||
do {
|
||||
numberOfBlankLines++;
|
||||
line = textEditor.getLine(thisLine
|
||||
+ numberOfLinesOfHeaderText
|
||||
+ numberOfBlankLines);
|
||||
} while ((line.length() == 0) || line.equals(""));
|
||||
// Note: 'st' is a reference to 'textEditor'...
|
||||
// delelete the header from the text in 'textEditor'
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText + numberOfBlankLines);
|
||||
textEditor.setSelection(start, finish);
|
||||
textEditor.setEditable(true);
|
||||
textEditor.invokeAction(SWT.DEL);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty
|
||||
// string.
|
||||
textEditor.setText("");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* If the first word begins with "ZCZC", it is a two-line header at
|
||||
* least, it is
|
||||
* "ZCZC CCNNNXXX adr\r\r\nTTAA00 KCCC DDHHMM bbb\r\r\n"
|
||||
*/
|
||||
int newLineIndex = prodText.indexOf("\n\n");
|
||||
String first = prodText.substring(0, newLineIndex);
|
||||
|
||||
try {
|
||||
start = 0;
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText) - 1;
|
||||
} catch (IllegalArgumentException e) {
|
||||
// The text does not span enough lines so use the full extent
|
||||
// of the product.
|
||||
finish = textEditor.getCharCount() - 1;
|
||||
}
|
||||
if (first.length() > 10) {
|
||||
String rest = prodText.substring(newLineIndex + 1);
|
||||
|
||||
// Set the content of the header block to consist of just the header
|
||||
// of
|
||||
// the text product... it will get reunited with the body when it is
|
||||
// saved.
|
||||
if (finish > start) {
|
||||
headerTF.setText(textEditor.getText(start, finish));
|
||||
} else {
|
||||
headerTF.setText("");
|
||||
}
|
||||
headerTF.setText(first);
|
||||
String cccnnnxxx = first.substring(5, 14);
|
||||
setCurrentSiteId("");
|
||||
setCurrentWmoId("");
|
||||
setCurrentWsfoId(cccnnnxxx.substring(0, 3));
|
||||
setCurrentProdCategory(cccnnnxxx.substring(3, 6));
|
||||
setCurrentProdDesignator(cccnnnxxx.substring(6, 9));
|
||||
|
||||
// Next, set the current body by assuming that it always
|
||||
// consists of the rest of the text product beyond the line(s)
|
||||
// of text in the header.
|
||||
try {
|
||||
int numberOfBlankLines = -1;
|
||||
String line = null;
|
||||
do {
|
||||
numberOfBlankLines++;
|
||||
line = textEditor.getLine(thisLine
|
||||
+ numberOfLinesOfHeaderText + numberOfBlankLines);
|
||||
} while ((line.length() == 0) || line.equals(""));
|
||||
// Note: 'st' is a reference to 'textEditor'...
|
||||
// delelete the header from the text in 'textEditor'
|
||||
finish = textEditor.getOffsetAtLine(thisLine
|
||||
+ numberOfLinesOfHeaderText + numberOfBlankLines);
|
||||
textEditor.setSelection(start, finish);
|
||||
textEditor.setEditable(true);
|
||||
textEditor.invokeAction(SWT.DEL);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty string.
|
||||
textEditor.setText("");
|
||||
try {
|
||||
textEditor.setText(rest.trim());
|
||||
textEditor.setEditable(true);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty
|
||||
// string.
|
||||
textEditor.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* If the first word begins with "ZCZC", it is a two-line header at least,
|
||||
* it is "ZCZC CCNNNXXX adr\r\r\nTTAA00 KCCC DDHHMM bbb\r\r\n"
|
||||
*/
|
||||
int newLineIndex = prodText.indexOf("\n\n");
|
||||
String first = prodText.substring(0, newLineIndex);
|
||||
|
||||
if (first.length() > 10 ) {
|
||||
String rest = prodText.substring(newLineIndex+1);
|
||||
|
||||
headerTF.setText(first);
|
||||
String cccnnnxxx = first.substring(5, 14);
|
||||
setCurrentSiteId("");
|
||||
setCurrentWmoId("");
|
||||
setCurrentWsfoId(cccnnnxxx.substring(0, 3));
|
||||
setCurrentProdCategory(cccnnnxxx.substring(3, 6));
|
||||
setCurrentProdDesignator(cccnnnxxx.substring(6, 9));
|
||||
|
||||
try {
|
||||
textEditor.setText(rest.trim());
|
||||
textEditor.setEditable(true);
|
||||
textEditor.setEditable(false);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// There is no text product body, so set it to the empty string.
|
||||
textEditor.setText("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7951,7 +7965,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
}
|
||||
|
||||
// is this the pathcast paragragh?
|
||||
if (paragraphStart.startsWith("* THIS") && paragraphStart.endsWith("WILL BE NEAR...")) {
|
||||
if (paragraphStart.startsWith("* THIS")
|
||||
&& paragraphStart.endsWith("WILL BE NEAR...")) {
|
||||
inPathcast = true;
|
||||
}
|
||||
|
||||
|
@ -7964,8 +7979,10 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
padding = " ";
|
||||
}
|
||||
|
||||
if ((inLocations || inPathcast) && (paragraphStartLineNumber == lineNumber)) {
|
||||
// Keep LOCATIONS and PATHCAST first line short & don't paste more to it.
|
||||
if ((inLocations || inPathcast)
|
||||
&& (paragraphStartLineNumber == lineNumber)) {
|
||||
// Keep LOCATIONS and PATHCAST first line short & don't paste more
|
||||
// to it.
|
||||
if (line.indexOf("...") == line.lastIndexOf("...")) {
|
||||
return;
|
||||
}
|
||||
|
@ -8045,11 +8062,11 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
&& (allText.charAt(eol + 1) == '\n')) {
|
||||
deleteLen = 2;
|
||||
} else if (allText.charAt(eol) == '\n') {
|
||||
if (allText.charAt(eol-1) == '.' && allText.charAt(eol-2) != '.') {
|
||||
if ((allText.charAt(eol - 1) == '.')
|
||||
&& (allText.charAt(eol - 2) != '.')) {
|
||||
// do not extend this line.
|
||||
return;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
deleteLen = 1;
|
||||
}
|
||||
} else {
|
||||
|
@ -8197,8 +8214,8 @@ public class TextEditorDialog extends CaveSWTDialog implements VerifyListener,
|
|||
}
|
||||
textEditor.replaceTextRange(position, 0, replacement.toString());
|
||||
// remove and extra space
|
||||
if (textEditor.getText(position -1, position - 1).equals(" ")) {
|
||||
textEditor.replaceTextRange(position-1, 1, "");
|
||||
if (textEditor.getText(position - 1, position - 1).equals(" ")) {
|
||||
textEditor.replaceTextRange(position - 1, 1, "");
|
||||
}
|
||||
++endWrapLine;
|
||||
}
|
||||
|
|
|
@ -64,15 +64,15 @@ public interface IQCCheck {
|
|||
|
||||
public static final Pattern firstBulletPtrn = Pattern.compile(
|
||||
"^\\*\\s(.*)\\s(WARNING|ADVISORY)(\\sFOR(.*)|...)",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
|
||||
|
||||
public static final Pattern secondBulletPtrn = Pattern.compile(
|
||||
"^\\*\\sUNTIL\\s(\\d{1,2})(\\d{2})\\s(AM|PM)\\s(\\w{3,4})",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
|
||||
|
||||
public static final Pattern thirdBulletPtrn = Pattern.compile(
|
||||
"^\\*\\sAT\\s(\\d{1,2})(\\d{2})\\s(AM|PM)\\s(\\w{3,4})(.*)",
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
|
||||
|
||||
public static final Pattern latLonPtrn = Pattern
|
||||
.compile("LAT...LON+(\\s\\d{3,4}\\s\\d{3,5}){1,}");
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
# Date Ticket# Engineer Description
|
||||
# ------------ ---------- ----------- --------------------------
|
||||
# 05/07/2015 4027 randerso Migrated A1 OB9.16 code to A2
|
||||
# 06/17/2015 4027 dgilling Perform case-insensitive
|
||||
# comparisons in foundCTAs.
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
# Description: This product is a template for creating Hazard Products.
|
||||
|
@ -1148,7 +1150,9 @@ class TextProduct(TextRules.TextRules, SampleAnalysis.SampleAnalysis,
|
|||
for (ctaType, cta) in self.__procCTA:
|
||||
## Added following line to account for framing code issues in CTA
|
||||
cta = re.sub("\|\*.*\*\|","",cta)
|
||||
if para == cta and ctaType not in found:
|
||||
# We want this comparison to be case-insensitive just in case
|
||||
# the site is not transmitting in mixed case yet.
|
||||
if para.upper() == cta.upper() and ctaType not in found:
|
||||
found.append(ctaType)
|
||||
return found
|
||||
|
||||
|
|
|
@ -79,9 +79,9 @@ near ${singType}${list.get(${markers},0).name}.
|
|||
#set($marker1 = ${list.get(${markers},${startCounter}).name})
|
||||
#set($marker2 = ${list.get(${markers},${endCounter}).name})
|
||||
#if(${startCounter} == ${endCounter})
|
||||
near ${singType}${marker1}...##
|
||||
near ${singType}${marker1}, ##
|
||||
#else
|
||||
between ${plurType}${marker1} and ${marker2}...##
|
||||
between ${plurType}${marker1} and ${marker2}, ##
|
||||
#end
|
||||
#set($phraseCount = $phraseCount + 1)
|
||||
#set($startIdx = $intIndex)
|
||||
|
@ -108,7 +108,7 @@ ${singType}${marker1} and near ${singType}${marker2}.
|
|||
#set($marker1 = ${list.get(${markers},${startCounter}).name})
|
||||
#set($marker2 = ${list.get(${markers},${endCounter}).name})
|
||||
#set($marker3 = ${list.get(${markers},${counter}).name})
|
||||
between ${plurType}${marker1} and ${marker2}...and near ${singType}${marker3}.
|
||||
between ${plurType}${marker1} and ${marker2}, and near ${singType}${marker3}.
|
||||
#end
|
||||
#end
|
||||
#set($counter = $counter + 1)
|
||||
|
@ -118,11 +118,11 @@ near ${plurType}##
|
|||
#foreach($item in $markers)
|
||||
#set($counter = $counter + 1)
|
||||
#if($size > 1 && $counter == $size)
|
||||
AND ${item.name}.
|
||||
and ${item.name}.
|
||||
#elseif($size == 1 && $counter == $size)
|
||||
${item.name}.
|
||||
#else
|
||||
${item.name}...##
|
||||
${item.name}, ##
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
@ -479,7 +479,7 @@ along a line extending from #outputLineOfStorms($used1, $nearText, $nearThreshol
|
|||
#set($used2 = [])
|
||||
#lineOfStorms($used2, $used, $points2, $threshold, $units)
|
||||
#if(${used1.size()} == ${used2.size()})
|
||||
...or along a line extending from #outputLineOfStorms($used2, $nearText, $nearThreshold, $overThreshold, $units)##
|
||||
, or along a line extending from #outputLineOfStorms($used2, $nearText, $nearThreshold, $overThreshold, $units)##
|
||||
#end
|
||||
#end
|
||||
#else
|
||||
|
@ -503,11 +503,11 @@ ${point1.roundedDistance} #capitalize($units "NONE") #direction(${point1.opposit
|
|||
${location}##
|
||||
#if($point2 && $useSecondRef && ${point2.name} != ${point1.name})
|
||||
#if($point2.roundedDistance <= $overThreshold)
|
||||
...or ${overText} ##
|
||||
, or ${overText} ##
|
||||
#elseif($point2.roundedDistance <= $nearThreshold)
|
||||
...or ${nearText} ##
|
||||
, or ${nearText} ##
|
||||
#else
|
||||
...or ${point2.roundedDistance} #capitalize($units "NONE") #direction(${point2.oppositeRoundedAzimuth}) of ##
|
||||
, or ${point2.roundedDistance} #capitalize($units "NONE") #direction(${point2.oppositeRoundedAzimuth}) of ##
|
||||
#end
|
||||
#if(${point2.partOfArea})
|
||||
#set($location = "#areaFormat(${point2.partOfArea} true false false) ${point2.name}")
|
||||
|
@ -1259,6 +1259,7 @@ Until ${dateUtil.formatUseNoonMidnight(${expire}, ${timeFormat.clock}, 15, ${loc
|
|||
/${dateUtil.formatUseNoonMidnight(${expire}, ${timeFormat.clock}, 15, ${secondtimezone})}/##
|
||||
#end
|
||||
#end
|
||||
.
|
||||
#end
|
||||
########END MACRO
|
||||
|
||||
|
@ -1308,8 +1309,8 @@ At ${dateUtil.format(${time}, ${timeFormat.clock}, ${localtimezone})}##
|
|||
## This macro will output a pathcast based on the thresholds/parameters
|
||||
## defined in the product's .xml configuration file
|
||||
## 1 - These dangerous storms will be near...
|
||||
## Kansas City...Independence...Grain Valley around 800 PM CDT...
|
||||
## Lee's Summit...Grandview...Raytown around 805 PM CDT...
|
||||
## Kansas City, Independence, Grain Valley around 800 PM CDT.
|
||||
## Lee's Summit, Grandview, Raytown around 805 PM CDT.
|
||||
## Inputs: pathcastLead (string containing a lead-in to the pathcast)
|
||||
## otherLead (string containing a lead-in to the list of other (typically 3rd level) towns
|
||||
## pathCast (array of ClosestPoint objects)
|
||||
|
@ -1343,7 +1344,7 @@ ${pathcastLead}
|
|||
#if($count == $numCities - 1)
|
||||
#set($output = "${output} and ")
|
||||
#elseif($count < $numCities)
|
||||
#set($output = "${output}...")
|
||||
#set($output = "${output}, ")
|
||||
#end
|
||||
#end
|
||||
#set($output = "${output} around ${dateUtil.format(${pc.time}, ${timeFormat.clock}, ${pc.timeZone})}.")
|
||||
|
@ -1368,7 +1369,7 @@ ${location}##
|
|||
#if($count == $numOtherPoints - 1)
|
||||
and ##
|
||||
#elseif($count < $numOtherPoints)
|
||||
...##
|
||||
, ##
|
||||
#else
|
||||
.
|
||||
#end
|
||||
|
@ -1384,7 +1385,7 @@ ${otherLead} will remain over ${noLocPhrase} of ##
|
|||
### NEED TO CODE THIS ONCE SECTION IS ADDED
|
||||
#set($numOtherPoints = ${list.size($otherPoints)})
|
||||
#if($numOtherPoints > 0)
|
||||
...including the following locations...##
|
||||
, including the following locations: ##
|
||||
#set($count = 0)
|
||||
#foreach(${loc} in ${otherPoints})
|
||||
#set($count = $count + 1)
|
||||
|
@ -1398,11 +1399,13 @@ ${location}##
|
|||
#if($count == $numOtherPoints - 1)
|
||||
and ##
|
||||
#elseif($count < $numOtherPoints)
|
||||
...##
|
||||
, ##
|
||||
#else
|
||||
.##
|
||||
#end
|
||||
#end
|
||||
#else
|
||||
.##
|
||||
#end
|
||||
|
||||
#end
|
||||
|
@ -1517,8 +1520,8 @@ ${inString}...##
|
|||
## Joppa... Phelan...
|
||||
## Arab... Wilburn...
|
||||
## 3 - Locations in the warning include but are not limited to...
|
||||
## Quinton...Susan Moore...West Jefferson...Warrior...Rosa,
|
||||
## Fairview...Locust Fork...Trafford, Argo(--- yourself), Anderson, and Alton
|
||||
## Quinton, Susan Moore, West Jefferson, Warrior, Rosa,
|
||||
## Fairview, Locust Fork, Trafford, Argo(--- yourself), Anderson, and Alton
|
||||
## Inputs: bulletLead (string containing a lead-in to the list of cities e.g. Locations Impacted Include...)
|
||||
## stormType (string containing the storm type e.g. severe thunderstorm)
|
||||
## columns (number of columns to list the cities (0 is a normal ellipsees separated list)
|
||||
|
@ -1544,7 +1547,7 @@ ${bulletLead}
|
|||
#set($count = $count + 1)
|
||||
#if($count < $numMajorPoints)
|
||||
#if($columns == 0)
|
||||
#set($strOutput = "${location}...")
|
||||
#set($strOutput = "${location}, ")
|
||||
#else
|
||||
#set($strOutput = "${location}...")
|
||||
#end
|
||||
|
@ -1600,7 +1603,7 @@ ${ruralPhrase} will remain over ${noLocPhrase} OF #headlineLocList(${areas} true
|
|||
#if(${numMinorPoints} == 1)
|
||||
, which includes ##
|
||||
#elseif(${numMinorPoints} > 1)
|
||||
, including the following locations...##
|
||||
, including the following locations: ##
|
||||
#else
|
||||
.##
|
||||
#end
|
||||
|
|
|
@ -217,11 +217,10 @@ THIS IS A TEST MESSAGE.##
|
|||
#### GP End
|
||||
|
||||
#if(${list.contains(${bullets}, "recedingWater")})
|
||||
THE HIGH WATER IS RECEDING...AND IS NO LONGER EXPECTED TO POSE A THREAT. PLEASE CONTINUE TO HEED ANY ROAD CLOSURES.
|
||||
|
||||
The high water is receding, and is no longer expected to pose a threat. Please continue to heed any road closures.
|
||||
#end
|
||||
#if(${list.contains(${bullets}, "rainEnded")})
|
||||
THE HEAVY RAIN HAS ENDED...AND FLOODING IS NO LONGER EXPECTED TO POSE A THREAT.
|
||||
The heavy rain has ended, and flooding is no longer expected to pose a threat.
|
||||
|
||||
#end
|
||||
#end
|
||||
|
|
|
@ -1 +1 @@
|
|||
20140807
|
||||
20150608
|
||||
|
|
99
rpms/legal/FOSS_licenses/Common_Public_License.txt
Normal file
99
rpms/legal/FOSS_licenses/Common_Public_License.txt
Normal file
|
@ -0,0 +1,99 @@
|
|||
Common Public License Version 1.0
|
||||
|
||||
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
|
||||
|
||||
1. DEFINITIONS
|
||||
|
||||
"Contribution" means:
|
||||
|
||||
a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
|
||||
|
||||
b) in the case of each subsequent Contributor:
|
||||
|
||||
i) changes to the Program, and
|
||||
|
||||
ii) additions to the Program;
|
||||
|
||||
where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in
|
||||
conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
|
||||
|
||||
"Contributor" means any person or entity that distributes the Program.
|
||||
|
||||
"Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
|
||||
|
||||
"Program" means the Contributions distributed in accordance with this Agreement.
|
||||
|
||||
"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
|
||||
|
||||
2. GRANT OF RIGHTS
|
||||
|
||||
a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
|
||||
|
||||
b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form.
|
||||
|
||||
This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
|
||||
|
||||
c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
|
||||
|
||||
d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
|
||||
|
||||
3. REQUIREMENTS
|
||||
|
||||
A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
|
||||
|
||||
a) it complies with the terms and conditions of this Agreement; and
|
||||
|
||||
b) its license agreement:
|
||||
|
||||
i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
|
||||
|
||||
ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
|
||||
|
||||
iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
|
||||
|
||||
iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
|
||||
|
||||
|
||||
|
||||
When the Program is made available in source code form:
|
||||
|
||||
a) it must be made available under this Agreement; and
|
||||
|
||||
b) a copy of this Agreement must be included with each copy of the Program.
|
||||
Contributors may not remove or alter any copyright notices contained within the Program.
|
||||
Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
|
||||
|
||||
4. COMMERCIAL DISTRIBUTION
|
||||
|
||||
Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if
|
||||
a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in
|
||||
connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
|
||||
|
||||
For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the
|
||||
Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
|
||||
|
||||
5. NO WARRANTY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
6. DISCLAIMER OF LIABILITY
|
||||
|
||||
EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
7. GENERAL
|
||||
|
||||
If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
|
||||
|
||||
If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
|
||||
|
||||
All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as
|
||||
reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
|
||||
|
||||
Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time.
|
||||
|
||||
No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its
|
||||
Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
|
||||
|
||||
This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
|
||||
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
Copyright (c) 2001, 2002 Enthought, Inc.
|
||||
All rights reserved.
|
||||
|
||||
Copyright (c) 2003-2012 SciPy Developers.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
a. Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
b. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
c. Neither the name of Enthought nor the names of the SciPy Developers
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
23
rpms/legal/FOSS_licenses/GPL_2.0.txt
Normal file
23
rpms/legal/FOSS_licenses/GPL_2.0.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
The GNU General Public License (GPL)
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.
|
|
@ -1,11 +0,0 @@
|
|||
Jython 2.0, 2.1 License
|
||||
|
||||
Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Jython Developers All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
Neither the name of the Jython Developers nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,24 +0,0 @@
|
|||
Copyright (c) 2004-2008 QOS.ch
|
||||
All rights reserved.
|
||||
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
rpms/legal/FOSS_licenses/qos.ch_c_2004-2013.txt
Normal file
1
rpms/legal/FOSS_licenses/qos.ch_c_2004-2013.txt
Normal file
|
@ -0,0 +1 @@
|
|||
Copyright (c) 2004-2013 QOS.ch All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Binary file not shown.
Loading…
Add table
Reference in a new issue