From b3f9ea79afa070295dde98c81cf5d8b2472a849b Mon Sep 17 00:00:00 2001 From: Roger Ferrel Date: Thu, 1 Aug 2013 09:10:14 -0500 Subject: [PATCH] Issue #2221 - Changes to have select configuration files for retention and case creation. Change-Id: Ia24898f04c3a2a626ea0aeb04c2c302e406afa1f Former-commit-id: 30f55459d26e3d1118610959e98e475ede0e9f47 --- .../raytheon/uf/viz/archive/data/SizeJob.java | 98 +++++++ .../uf/viz/archive/ui/AbstractArchiveDlg.java | 185 +++++++++++-- .../viz/archive/ui/ArchiveRetentionDlg.java | 86 +----- .../uf/viz/archive/ui/ArchiveTableComp.java | 21 +- .../uf/viz/archive/ui/CaseCreationDlg.java | 194 ++++++++++++- .../viz/archive/ui/CaseLoadSaveDeleteDlg.java | 259 ++++++++++++++++++ .../uf/viz/archive/ui/CaseNameDialog.java | 2 +- .../META-INF/MANIFEST.MF | 1 + .../archive/config/ArchiveConfigManager.java | 220 ++++++++++++++- .../archive/config/ArchiveConstants.java | 108 ++++++++ .../common/archive/config/SelectConfig.java | 192 +++++++++++++ .../archive/config/select/ArchiveSelect.java | 104 +++++++ .../archive/config/select/CategorySelect.java | 98 +++++++ .../common_static/base/roles/userRoles.xml | 4 + 14 files changed, 1436 insertions(+), 136 deletions(-) create mode 100644 cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseLoadSaveDeleteDlg.java create mode 100644 edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConstants.java create mode 100644 edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/SelectConfig.java create mode 100644 edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/ArchiveSelect.java create mode 100644 edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/CategorySelect.java diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java index 36f710c032..ab3148ca66 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java @@ -16,7 +16,16 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.ArchiveConstants; +import com.raytheon.uf.common.archive.config.ArchiveConstants.Type; import com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.common.archive.config.SelectConfig; +import com.raytheon.uf.common.archive.config.select.ArchiveSelect; +import com.raytheon.uf.common.archive.config.select.CategorySelect; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.time.util.TimeUtil; /** * Job to determine the size for a directory and its contents on a non-UI @@ -37,6 +46,8 @@ import com.raytheon.uf.common.archive.config.DisplayData; * @version 1.0 */ public class SizeJob extends Job { + private final IUFStatusHandler statusHandler = UFStatus + .getHandler(SizeJob.class); /** * Mapping of display data by archive and category names. @@ -222,6 +233,93 @@ public class SizeJob extends Job { return archiveInfoMap.keySet(); } + /** + * Check all displayData selection state so only the data in selections are + * set. + * + * @param selections + */ + public void loadSelect(String selectName, ArchiveConstants.Type type) { + ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + String fileName = ArchiveConstants.selectFileName(type, selectName); + SelectConfig selections = manager.loadSelection(fileName); + if (selections == null) { + selections = new SelectConfig(); + selections.setName(ArchiveConstants.defaultSelectName); + } + + for (String archiveName : getArchiveNames()) { + ArchiveInfo archiveInfo = get(archiveName); + for (String categoryName : archiveInfo.getCategoryNames()) { + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + List selectionsList = selections.getSelectedList( + archiveName, categoryName); + for (DisplayData displayData : categoryInfo + .getDisplayDataList()) { + String displayLabel = displayData.getDisplayLabel(); + boolean selected = selectionsList.contains(displayLabel); + if (selected != displayData.isSelected()) { + setSelect(archiveName, categoryName, displayLabel, + selected); + } + } + } + } + } + + /** + * Save selections to the desired file. + * + * @param selectName + * @param type + * @param startRetentionMS + * @return + */ + public String saveSelect(String selectName, ArchiveConstants.Type type, + long startRetentionMS) { + String errorMsg = null; + SelectConfig selections = new SelectConfig(); + selections.setName(selectName); + if (type == Type.Case) { + long startRetentionHours = startRetentionMS + / TimeUtil.MILLIS_PER_HOUR; + selections.setStarRetentionHours(startRetentionHours); + } + for (String archiveName : getArchiveNames()) { + ArchiveInfo archiveInfo = get(archiveName); + ArchiveSelect archiveSelect = new ArchiveSelect(); + archiveSelect.setName(archiveName); + for (String categoryName : archiveInfo.getCategoryNames()) { + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + CategorySelect categorySelect = new CategorySelect(); + categorySelect.setName(categoryName); + for (DisplayData displayData : categoryInfo + .getDisplayDataList()) { + if (displayData.isSelected()) { + categorySelect.add(displayData.getDisplayLabel()); + } + } + + if (!categorySelect.isEmpty()) { + archiveSelect.add(categorySelect); + } + } + if (!archiveSelect.isEmpty()) { + selections.add(archiveSelect); + } + } + String fileName = ArchiveConstants.selectFileName(type, selectName); + + try { + ArchiveConfigManager.getInstance().saveSelections(selections, + fileName); + } catch (Exception e) { + errorMsg = "Unable to save file: " + fileName; + statusHandler.handle(Priority.ERROR, errorMsg, e); + } + return errorMsg; + } + /** * Change the selection state and requeue size request. * diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java index 1e8fcff1fa..8ab82e3a20 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java @@ -28,27 +28,34 @@ 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.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.common.archive.config.ArchiveConfig; import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.ArchiveConstants; import com.raytheon.uf.common.archive.config.CategoryConfig; import com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.common.archive.config.SelectConfig; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; import com.raytheon.uf.common.util.SizeUtil; import com.raytheon.uf.viz.archive.data.ArchiveInfo; import com.raytheon.uf.viz.archive.data.CategoryInfo; import com.raytheon.uf.viz.archive.data.IArchiveTotals; import com.raytheon.uf.viz.archive.data.IUpdateListener; import com.raytheon.uf.viz.archive.data.SizeJob; -import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; @@ -66,6 +73,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * May 30, 2013 1965 bgonzale Initial creation * Jun 10, 2013 1966 rferrel Change to allow Case Creation to extend. * Jul 24, 2013 2220 rferrel Changes to queue size request for all data. + * Aug 01, 2013 2221 rferrel Changes for select configuration. * * * @author bgonzale @@ -73,7 +81,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; */ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements - IArchiveTotals, IUpdateListener { + IArchiveTotals, IUpdateListener, IModifyListener { /** Table composite that holds the table controls. */ private ArchiveTableComp tableComp; @@ -84,16 +92,13 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements /** Category combo box. */ private Combo categoryCbo; - /** - * Boolean to indicate when DisplayData is created should its selection be - * set based on the information in the configuration files. - */ - protected boolean setSelect = false; + /** Data manager. */ + protected ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); /** - * Must be set by sub-class prior to creating table. + * Must be set by sub-class prior to creating any components. */ - protected TableType tableType; + protected ArchiveConstants.Type type; /** * Job that computes sizes of table row entries off the UI thread. @@ -103,6 +108,15 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements /** Keeps track of when it is safe to clear the busy cursor. */ protected final AtomicInteger busyCnt = new AtomicInteger(0); + /** Performs save action button. */ + protected Button saveBtn; + + /** Flag set when user wants to close with unsaved modifications. */ + protected boolean closeFlag = false; + + /** Current select (case/retention) loaded into the dialog. */ + protected String selectName = ArchiveConstants.defaultSelectName; + /** * @param parentShell */ @@ -197,6 +211,11 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements */ protected abstract void setTotalSizeText(String sizeStringText); + /** + * This method is called by the AbstractArchiveDlg to set total Size. + * + * @param totalSize + */ protected abstract void setTotalSelectedItems(int totalSize); /** @@ -294,12 +313,13 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements } }); } - initDisplayData(); + final String titleName = initDisplayData(null); if (!shell.isDisposed()) { VizApp.runAsync(new Runnable() { @Override public void run() { + setSelectName(titleName); updateTableComp(); setCursorBusy(false); } @@ -308,14 +328,51 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements return Status.OK_STATUS; } }; + job.schedule(); + addModifiedListener(this); + shell.addShellListener(new ShellAdapter() { + + @Override + public void shellClosed(ShellEvent e) { + if (closeFlag || !isModified()) { + return; + } + + e.doit = false; + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + if (verifyClose()) { + close(); + } + } + }); + } + }); + } + + /** + * Change the select name and update the dialog's title. Assumes the + * sub-classes places a hyphen at the end of the string when setting the + * dialog's title. + * + * @param selectName + */ + protected void setSelectName(String selectName) { + this.selectName = selectName; + StringBuilder sb = new StringBuilder(getText()); + sb.setLength(sb.indexOf("-") + 1); + sb.append(" ").append(selectName); + setText(sb.toString()); } /** * Create the table control. */ protected void createTable() { - tableComp = new ArchiveTableComp(shell, tableType, this, sizeJob); + tableComp = new ArchiveTableComp(shell, type, this, sizeJob); sizeJob.addUpdateListener(this); } @@ -341,7 +398,6 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements * Initial population up of the combo boxes. */ private void populateComboBoxes() { - ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); boolean doSelect = false; for (String archiveName : manager.getArchiveDataNamesList()) { archCfgCbo.add(archiveName); @@ -374,12 +430,12 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements private void initCategoryCbo() { String archiveName = getSelectedArchiveName(); - ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); categoryCbo.removeAll(); for (String categoryName : manager.getCategoryNames(archiveName)) { categoryCbo.add(categoryName); } categoryCbo.select(0); + categoryComboSelection(); } /** @@ -393,8 +449,14 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements * Set up all display data and queue getting sizes for any that are * selected. */ - private void initDisplayData() { - ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + protected String initDisplayData(String selectName) { + String fileName = ArchiveConstants.selectFileName(type, selectName); + SelectConfig selections = manager.loadSelection(fileName); + if (selections == null) { + selections = new SelectConfig(); + selections.setName(ArchiveConstants.defaultSelectName); + } + setRetentionTimes(selections.getStarRetentionHours()); String[] archiveNames = manager.getArchiveDataNamesList(); for (String archiveName : archiveNames) { ArchiveInfo archiveInfo = new ArchiveInfo(); @@ -405,15 +467,46 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements // move getting displayDatas into SizeJob then get current // display, displays with selections then other displays in the // background. + List selectedList = selections.getSelectedList( + archiveName, categoryName); List displayDatas = manager.getDisplayData( - archiveName, categoryName, setSelect); + archiveName, categoryName, false); CategoryInfo categoryInfo = new CategoryInfo(archiveName, categoryName, displayDatas); archiveInfo.add(categoryInfo); + for (DisplayData displayData : displayDatas) { + displayData.setSelected(selectedList.contains(displayData + .getDisplayLabel())); + } } sizeJob.put(archiveName, archiveInfo); } sizeJob.resetTime(getStart(), getEnd()); + return selections.getName(); + } + + /** + * Delete a select configuration file. + * + * @param selectName + */ + protected void deleteSelect(String selectName) { + String fileName = ArchiveConstants.selectFileName(type, selectName); + try { + manager.deleteSelection(fileName); + } catch (LocalizationOpFailedException e) { + MessageDialog.openError(shell, "Case Error", + "Unable to delete file: " + fileName); + } + } + + /** + * Load a select configuration file. + * + * @param selectName + */ + protected void loadSelect(String selectName) { + sizeJob.loadSelect(selectName, type); } /** @@ -529,6 +622,7 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements } } } + VizApp.runAsync(new Runnable() { @Override @@ -594,4 +688,63 @@ public abstract class AbstractArchiveDlg extends CaveSWTDialog implements sizeJob.recomputeSize(); populateTableComp(); } + + /** + * Allows a sub-class to set the start and end times based on the off set. + * + * @param startTimeOffset + */ + protected void setRetentionTimes(long startTimeOffset) { + // do nothing override by sub-classes + } + + /** + * Indicate unsaved user changes. + * + * @return modified + */ + protected boolean isModified() { + return (saveBtn != null) && !saveBtn.isDisposed() + && saveBtn.isEnabled(); + } + + /** + * Save current selections of the select configuration file. + * + * @param selectName + * @return true when save is successful + */ + protected boolean saveSelection(String selectName) { + Calendar start = getStart(); + Calendar end = getEnd(); + long startRetentionMS = 0L; + if (start != null && end != null) { + startRetentionMS = end.getTimeInMillis() - start.getTimeInMillis(); + } + String errorMsg = sizeJob + .saveSelect(selectName, type, startRetentionMS); + if (errorMsg != null) { + MessageDialog.openError(shell, type + " Selection Error", errorMsg); + } + + return errorMsg == null; + } + + /** + * When unsaved modifications this asks the user to verify the close. + * + * @return true when okay to close. + */ + protected boolean verifyClose() { + boolean state = true; + if (isModified()) { + MessageBox box = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK + | SWT.CANCEL); + box.setText("Close " + type); + box.setMessage("Unsave changes.\nSelect OK to discard changes."); + state = box.open() == SWT.OK; + } + closeFlag = state; + return state; + } } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java index c7231bfeb3..58f4a2e428 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java @@ -25,8 +25,6 @@ import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.ShellAdapter; -import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -34,15 +32,11 @@ import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; -import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.ArchiveConstants.Type; import com.raytheon.uf.common.archive.config.DisplayData; -import com.raytheon.uf.viz.archive.data.IArchiveTotals; -import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType; -import com.raytheon.uf.viz.core.VizApp; /** * Archive retention dialog. @@ -57,14 +51,14 @@ import com.raytheon.uf.viz.core.VizApp; * May 31, 2013 #1965 bgonzale Initial work for updating retention configurations. * Jun 10, 2013 #1966 rferrel Implemented hooks to get display and save to work. * Jul 24, 2013 #2220 rferrel Add recompute size button. + * Jul 24, 2013 #2221 rferrel Changes for select configuration. * * * * @author lvenable * @version 1.0 */ -public class ArchiveRetentionDlg extends AbstractArchiveDlg implements - IArchiveTotals, IModifyListener { +public class ArchiveRetentionDlg extends AbstractArchiveDlg { /** Current Archive/Category selection's minimum retention hours. */ private RetentionHours minRetention; @@ -78,12 +72,6 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements /** Displays the total size of selected items. */ private Label totalSizeLbl; - /** Performs save action button. */ - private Button saveBtn; - - /** Flag set when user wants to close with unsaved modifications. */ - boolean closeFlag = false; - /** * Constructor. * @@ -93,8 +81,7 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements public ArchiveRetentionDlg(Shell parentShell) { super(parentShell, SWT.DIALOG_TRIM | SWT.MIN, CAVE.DO_NOT_BLOCK | CAVE.MODE_INDEPENDENT | CAVE.INDEPENDENT_SHELL); - this.setSelect = true; - this.tableType = TableType.Retention; + this.type = Type.Retention; } /* @@ -121,7 +108,7 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements @Override protected void initializeComponents(Shell shell) { super.initializeComponents(shell); - setText("Archive Retention"); + setText("Archive Retention -"); Composite mainComp = new Composite(shell, SWT.NONE); GridLayout gl = new GridLayout(1, false); gl.marginHeight = 0; @@ -236,9 +223,7 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements saveBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent selectionEvent) { - ArchiveConfigManager manager = ArchiveConfigManager - .getInstance(); - manager.save(); + saveSelection(selectName); saveBtn.setEnabled(false); clearModified(); } @@ -271,24 +256,6 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements }); } - /** - * When unsaved modifications this asks the user to verify the close. - * - * @return true when okay to close. - */ - private boolean verifyClose() { - boolean state = true; - if (isModified()) { - MessageBox box = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK - | SWT.CANCEL); - box.setText("Close Retention"); - box.setMessage("Unsave changes.\nSelect OK to continue."); - state = box.open() == SWT.OK; - } - closeFlag = state; - return state; - } - /* * (non-Javadoc) * @@ -403,37 +370,6 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements extRetention.clearModified(); } - /* - * (non-Javadoc) - * - * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#preOpened() - */ - @Override - protected void preOpened() { - super.preOpened(); - addModifiedListener(this); - shell.addShellListener(new ShellAdapter() { - - @Override - public void shellClosed(ShellEvent e) { - if (closeFlag || !isModified()) { - return; - } - - e.doit = false; - VizApp.runAsync(new Runnable() { - - @Override - public void run() { - if (verifyClose()) { - close(); - } - } - }); - } - }); - } - /* * (non-Javadoc) * @@ -446,14 +382,4 @@ public class ArchiveRetentionDlg extends AbstractArchiveDlg implements removeModifiedListener(this); super.disposed(); } - - /** - * Indicate unsaved user changes. - * - * @return modified - */ - private boolean isModified() { - return (saveBtn != null) && !saveBtn.isDisposed() - && saveBtn.isEnabled(); - } } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java index ef261f46cc..ea15de242f 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java @@ -42,6 +42,8 @@ import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; +import com.raytheon.uf.common.archive.config.ArchiveConstants; +import com.raytheon.uf.common.archive.config.ArchiveConstants.Type; import com.raytheon.uf.common.archive.config.DisplayData; import com.raytheon.uf.common.util.SizeUtil; import com.raytheon.uf.viz.archive.data.IArchiveTotals; @@ -57,6 +59,7 @@ import com.raytheon.uf.viz.archive.data.SizeJob; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * May 23, 2013 #1964 lvenable Initial creation + * Jul 24, 2013 #2221 rferrel Changes for select configuration. * * * @@ -89,13 +92,8 @@ public class ArchiveTableComp extends Composite { /** Size label. */ private Label sizeLbl; - /** Table type enumeration. */ - public enum TableType { - Retention, Case - }; - - /** Current table type. */ - private final TableType type; + /** The dialog's type. */ + private final ArchiveConstants.Type type; /** Allows the parent dialog log to update other total displays. */ private final IArchiveTotals iArchiveTotals; @@ -126,7 +124,7 @@ public class ArchiveTableComp extends Composite { * @param type * Table type. */ - public ArchiveTableComp(Composite parent, TableType type, + public ArchiveTableComp(Composite parent, Type type, IArchiveTotals iTotalSelectedSize, SizeJob sizeJob) { super(parent, 0); @@ -150,7 +148,7 @@ public class ArchiveTableComp extends Composite { createTable(); - if (type != TableType.Retention) { + if (type != Type.Retention) { createTableLabels(); } } @@ -186,9 +184,9 @@ public class ArchiveTableComp extends Composite { pathColumn.setText("Label"); TableColumn sizeColumn = new TableColumn(table, SWT.CENTER); - if (type == TableType.Retention) { + if (type == Type.Retention) { sizeColumn.setText("Current Size"); - } else if (type == TableType.Case) { + } else if (type == Type.Case) { sizeColumn.setText("Size"); } @@ -460,6 +458,7 @@ public class ArchiveTableComp extends Composite { table.setSortColumn(table.getColumn(LABEL_COL_INDEX)); table.setSortDirection(SWT.UP); table.clearAll(); + updateSelectionLabels(); } /** diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java index 63c0b64bd7..86929c8c6a 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java @@ -47,12 +47,10 @@ import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; +import com.raytheon.uf.common.archive.config.ArchiveConstants.Type; import com.raytheon.uf.common.archive.config.DisplayData; import com.raytheon.uf.common.time.util.TimeUtil; import com.raytheon.uf.common.util.SizeUtil; -import com.raytheon.uf.viz.archive.data.IArchiveTotals; -import com.raytheon.uf.viz.archive.data.IUpdateListener; -import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType; import com.raytheon.uf.viz.core.VizApp; import com.raytheon.viz.ui.dialogs.AwipsCalendar; import com.raytheon.viz.ui.dialogs.ICloseCallback; @@ -71,14 +69,14 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * Jun 10, 2013 #1966 rferrel Implemented back in hooks for display * and generation of cases. * Jul 24, 2013 #2220 rferrel Add recompute size button. + * Jul 24, 2013 #2221 rferrel Changes for select configuration. * * * * @author lvenable * @version 1.0 */ -public class CaseCreationDlg extends AbstractArchiveDlg implements - IArchiveTotals, IUpdateListener { +public class CaseCreationDlg extends AbstractArchiveDlg { /** Start time label. */ private Label startTimeLbl; @@ -104,6 +102,15 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements /** Break files check box. */ private Button breakFilesChk; + /** Button to save new select case configuration. */ + private Button saveAsBtn; + + /** Button to load select case configuration. */ + private Button loadBtn; + + /** Button to delete select case configuration. */ + private Button deleteBtn; + /** File size spinner control. */ private Spinner fileSizeSpnr; @@ -135,6 +142,15 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements /** Number of selected items. */ private int selectedItemsSize = 0; + /** Dialog to create new select case. */ + private CaseLoadSaveDeleteDlg saveAsDlg; + + /** Dialog to load a select case. */ + private CaseLoadSaveDeleteDlg loadDlg; + + /** Dialog to delete a select case. */ + private CaseLoadSaveDeleteDlg deleteDlg; + /** * Constructor. * @@ -144,8 +160,7 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements public CaseCreationDlg(Shell parentShell) { super(parentShell, SWT.DIALOG_TRIM | SWT.MIN, CAVE.DO_NOT_BLOCK | CAVE.MODE_INDEPENDENT | CAVE.INDEPENDENT_SHELL); - this.setSelect = false; - this.tableType = TableType.Case; + this.type = Type.Case; } /* @@ -173,7 +188,7 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements @Override protected void initializeComponents(Shell shell) { super.initializeComponents(shell); - setText("Archive Case Creation"); + setText("Archive Case Creation -"); Composite mainComp = new Composite(shell, SWT.NONE); GridLayout gl = new GridLayout(1, false); gl.marginHeight = 0; @@ -235,13 +250,29 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements gd = new GridData(220, SWT.DEFAULT); endTimeLbl = new Label(timeComp, SWT.BORDER); endTimeLbl.setLayoutData(gd); + } + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#setRetentionTimes(long) + */ + @Override + protected void setRetentionTimes(long startRetentionHours) { + long startTimeOffset = startRetentionHours * TimeUtil.MILLIS_PER_HOUR; endDate = TimeUtil.newDate(); long time = endDate.getTime(); - time -= TimeUtil.MILLIS_PER_DAY; + time -= startTimeOffset; startDate = new Date(time); - startTimeLbl.setText(dateFmt.format(startDate)); - endTimeLbl.setText(dateFmt.format(endDate)); + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + startTimeLbl.setText(dateFmt.format(startDate)); + endTimeLbl.setText(dateFmt.format(endDate)); + } + }); } /** @@ -422,7 +453,7 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements private void createBottomActionButtons() { Composite actionControlComp = new Composite(shell, SWT.NONE); - GridLayout gl = new GridLayout(3, false); + GridLayout gl = new GridLayout(7, false); GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); actionControlComp.setLayout(gl); actionControlComp.setLayoutData(gd); @@ -438,6 +469,44 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements // } // }); + saveBtn = new Button(actionControlComp, SWT.PUSH); + saveBtn.setText(" Save "); + saveBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent selectionEvent) { + saveSelection(selectName); + clearModified(); + } + }); + saveBtn.setEnabled(false); + + saveAsBtn = new Button(actionControlComp, SWT.PUSH); + saveAsBtn.setText(" Save As... "); + saveAsBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent selectionEvent) { + handleSaveAsCase(); + } + }); + + loadBtn = new Button(actionControlComp, SWT.PUSH); + loadBtn.setText(" Load... "); + loadBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent selectionEvent) { + handleLoadCase(); + } + }); + + deleteBtn = new Button(actionControlComp, SWT.PUSH); + deleteBtn.setText(" Delete... "); + deleteBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent selectionEvent) { + handleDeleteCase(); + } + }); + generateBtn = new Button(actionControlComp, SWT.PUSH); generateBtn.setText(" Generate "); generateBtn.setEnabled(false); @@ -465,11 +534,89 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements closeBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - close(); + if (verifyClose()) { + close(); + } else { + e.doit = false; + } } }); } + private void handleSaveAsCase() { + if (saveAsDlg == null || saveAsDlg.isDisposed()) { + saveAsDlg = new CaseLoadSaveDeleteDlg(shell, + CaseLoadSaveDeleteDlg.Type.SaveAs); + saveAsDlg.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof String) { + String name = returnValue.toString(); + if (saveSelection(name)) { + clearModified(); + loadSelect(name); + setSelectName(name); + } + } + } + }); + saveAsDlg.open(); + } else { + saveAsDlg.bringToTop(); + } + } + + private void handleLoadCase() { + if (isModified() + && !MessageDialog.openConfirm(shell, "Case Confirmation", + "Unsave changes will be lost.\nPress OK to continue.")) { + return; + + } + if (loadDlg == null || loadDlg.isDisposed()) { + loadDlg = new CaseLoadSaveDeleteDlg(shell, + CaseLoadSaveDeleteDlg.Type.Load); + loadDlg.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof String) { + String name = returnValue.toString(); + loadSelect(name); + populateTableComp(); + updateTotals(null); + setSelectName(name); + clearModified(); + } + } + }); + loadDlg.open(); + } else { + loadDlg.bringToTop(); + } + } + + private void handleDeleteCase() { + if (deleteDlg == null || deleteDlg.isDisposed()) { + deleteDlg = new CaseLoadSaveDeleteDlg(shell, + CaseLoadSaveDeleteDlg.Type.Delete); + deleteDlg.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof String) { + String selectName = returnValue.toString(); + deleteSelect(selectName); + } + } + }); + deleteDlg.open(); + } else { + deleteDlg.bringToTop(); + } + } + /** * Display modal dialog that performs the Generation of the case. */ @@ -782,4 +929,25 @@ public class CaseCreationDlg extends AbstractArchiveDlg implements endCal.setTimeInMillis(endDate.getTime()); return endCal; } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.IModifyListener#modified() + */ + @Override + public void modified() { + saveBtn.setEnabled(true); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#clearModified() + */ + @Override + public void clearModified() { + super.clearModified(); + saveBtn.setEnabled(false); + } } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseLoadSaveDeleteDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseLoadSaveDeleteDlg.java new file mode 100644 index 0000000000..5d3ad1428c --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseLoadSaveDeleteDlg.java @@ -0,0 +1,259 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.viz.archive.ui; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.List; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.ArchiveConstants; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Dialog to display a list of select files for Load, Save As or Delete. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 31, 2013 2221       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class CaseLoadSaveDeleteDlg extends CaveSWTDialog { + public static enum Type { + SaveAs("Save As", " Save "), Load("Load", " Load "), Delete("Delete", + " Delete "); + private String title; + + private String btnLabel; + + private Type(String title, String btnLabel) { + this.title = title; + this.btnLabel = btnLabel; + } + + public String getTitle() { + return title; + } + + public String getBtnLabel() { + return btnLabel; + } + } + + private Type type; + + private List caseList; + + private Text fileNameText; + + private Button okBtn; + + private Button cancelBtn; + + protected CaseLoadSaveDeleteDlg(Shell parentShell, Type type) { + super(parentShell, SWT.DIALOG_TRIM | SWT.RESIZE, CAVE.DO_NOT_BLOCK); + this.type = type; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org + * .eclipse.swt.widgets.Shell) + */ + @Override + protected void initializeComponents(Shell shell) { + setText(type.getTitle() + " Case"); + Composite mainComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.horizontalSpacing = 0; + mainComp.setLayout(gl); + init(); + } + + /** + * Set up dialog layout. + */ + private void init() { + createCaseControls(); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); + createBottomAcitonButtons(); + } + + /** + * Main body of the dialog. + */ + private void createCaseControls() { + Composite caseComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + caseComp.setLayout(gl); + caseComp.setLayoutData(gd); + + caseList = new List(caseComp, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.minimumHeight = 300; + caseList.setLayoutData(gd); + + caseList.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + fileNameText.setText(caseList.getSelection()[0]); + } + }); + + fileNameText = new Text(caseComp, SWT.BORDER | SWT.SINGLE); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + fileNameText.setLayoutData(gd); + fileNameText.setEditable(type == Type.SaveAs); + } + + /** + * Button layout at the bottom of the dialog. + */ + private void createBottomAcitonButtons() { + Composite actionControlComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + actionControlComp.setLayout(gl); + actionControlComp.setLayoutData(gd); + okBtn = new Button(actionControlComp, SWT.PUSH); + okBtn.setText(type.getBtnLabel()); + okBtn.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + String name = verifyAction(); + if (name != null) { + setReturnValue(name); + close(); + } + } + }); + + cancelBtn = new Button(actionControlComp, SWT.PUSH); + cancelBtn.setText(" Cancel "); + gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false); + cancelBtn.setLayoutData(gd); + cancelBtn.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + }); + } + + /** + * Verify pending action and return select case name to continue the action. + * + * @return name when ok to perform action otherwise null + */ + private String verifyAction() { + String name = fileNameText.getText().trim(); + + if (name.isEmpty()) { + MessageDialog.openError(shell, "Case Error", "Invalid case name."); + name = null; + } else { + switch (type) { + case Load: + // No need to check since text is not editable. + break; + case SaveAs: + for (String cName : caseList.getItems()) { + if (name.equals(cName)) { + boolean response = MessageDialog + .openConfirm( + shell, + "Case Confirmation", + "Case \"" + + name + + "\" exists.\nSelect OK to overwrite."); + if (!response) { + name = null; + fileNameText.selectAll(); + fileNameText.forceFocus(); + } + break; + } + } + break; + case Delete: + if (!MessageDialog.openConfirm(shell, "Case Confirmation", + "Press OK to delete \"" + name + "\".")) { + name = null; + } + break; + default: + name = null; + } + } + return name; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialog#preOpened() + */ + @Override + protected void preOpened() { + super.preOpened(); + populateList(); + } + + /** + * Populate case names in the list. + */ + private void populateList() { + caseList.add(ArchiveConstants.defaultSelectName); + String[] names = ArchiveConfigManager.getInstance().getSelectionNames( + ArchiveConstants.Type.Case); + for (String name : names) { + if (!ArchiveConstants.defaultSelectName.equals(name)) { + caseList.add(name); + } + } + caseList.select(0); + fileNameText.setText(caseList.getItem(0)); + } +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java index 60a5e16b54..e40aaee621 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java @@ -98,7 +98,7 @@ public class CaseNameDialog extends CaveSWTDialog { } /** - * The xomposite with case name text field. + * The composite with case name text field. */ private void createFieldsComp() { Composite fieldComp = new Composite(shell, SWT.NONE); diff --git a/edexOsgi/com.raytheon.uf.common.archive/META-INF/MANIFEST.MF b/edexOsgi/com.raytheon.uf.common.archive/META-INF/MANIFEST.MF index 7fa1445e69..fb1b6e2af0 100644 --- a/edexOsgi/com.raytheon.uf.common.archive/META-INF/MANIFEST.MF +++ b/edexOsgi/com.raytheon.uf.common.archive/META-INF/MANIFEST.MF @@ -6,6 +6,7 @@ Bundle-Version: 1.0.0.qualifier Bundle-Vendor: RAYTHEON Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Export-Package: com.raytheon.uf.common.archive.config, + com.raytheon.uf.common.archive.config.select, com.raytheon.uf.common.archive.exception Require-Bundle: com.raytheon.uf.common.util, com.raytheon.uf.common.localization, diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java index ae9dc87732..48a2b3a2aa 100644 --- a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConfigManager.java @@ -21,6 +21,8 @@ package com.raytheon.uf.common.archive.config; import java.io.File; import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; import java.text.FieldPosition; import java.text.MessageFormat; @@ -46,6 +48,9 @@ import org.apache.commons.io.filefilter.FileFilterUtils; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.RegexFileFilter; +import com.raytheon.uf.common.archive.config.ArchiveConstants.Type; +import com.raytheon.uf.common.archive.config.select.ArchiveSelect; +import com.raytheon.uf.common.archive.config.select.CategorySelect; import com.raytheon.uf.common.archive.exception.ArchiveException; import com.raytheon.uf.common.localization.IPathManager; import com.raytheon.uf.common.localization.LocalizationContext; @@ -56,6 +61,7 @@ import com.raytheon.uf.common.localization.LocalizationFileInputStream; import com.raytheon.uf.common.localization.LocalizationFileOutputStream; import com.raytheon.uf.common.localization.PathManagerFactory; import com.raytheon.uf.common.localization.exception.LocalizationException; +import com.raytheon.uf.common.localization.exception.LocalizationOpFailedException; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; import com.raytheon.uf.common.status.UFStatus.Priority; @@ -78,6 +84,7 @@ import com.raytheon.uf.common.util.FileUtil; * Added null check for topLevelDirs in purgeExpiredFromArchive. * Changed to use File.delete() instead of Apache FileUtil.deleteQuietly(). * Added warn logging for failure to delete. + * Jul 24, 2013 2221 rferrel Changes for select configuration. * * * @@ -95,7 +102,7 @@ public class ArchiveConfigManager { public final String ARCHIVE_DIR = "archiver/purger"; /** Localization manager. */ - private IPathManager pathMgr; + protected IPathManager pathMgr; private final Map archiveNameToLocalizationFileMap = new HashMap(); @@ -171,9 +178,34 @@ public class ArchiveConfigManager { } /** + * Obtain the collection of Archives setting the Categories' selections + * based on the default retention selections. + * * @return the Collection of Archives. */ public Collection getArchives() { + String fileName = ArchiveConstants.selectFileName(Type.Retention, null); + SelectConfig selections = loadSelection(fileName); + if (selections != null && !selections.isEmpty()) { + try { + for (ArchiveSelect archiveSelect : selections.getArchiveList()) { + ArchiveConfig archiveConfig = archiveMap.get(archiveSelect + .getName()); + for (CategorySelect categorySelect : archiveSelect + .getCategorySelectList()) { + CategoryConfig categoryConfig = archiveConfig + .getCategory(categorySelect.getName()); + categoryConfig.setSelectedDisplayNames(categorySelect + .getSelectList()); + } + } + } catch (NullPointerException ex) { + statusHandler + .handle(Priority.ERROR, + "Retention selection and Archive configuration no longer in sync: ", + ex); + } + } return archiveMap.values(); } @@ -630,20 +662,6 @@ public class ArchiveConfigManager { return resultDirs; } - /** - * Get the Display labels matching the pattern for the archive data's - * category. Assumes the archive data's root directory is the mount point to - * start the search. - * - * @param archiveName - * @param categoryName - * @return displayInfoList order by display label - */ - public List getDisplayData(String archiveName, - String categoryName) { - return getDisplayData(archiveName, categoryName, false); - } - /** * Get the Display labels matching the pattern for the archive data's * category. Assumes the archive data's root directory is the mount point to @@ -788,4 +806,176 @@ public class ArchiveConfigManager { return archiveConfig; } + /** + * Delete the selection localized site configuration file. + * + * @param fileName + * @throws LocalizationOpFailedException + */ + public void deleteSelection(String fileName) + throws LocalizationOpFailedException { + LocalizationContext siteContext = pathMgr.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); + LocalizationFile lFile = pathMgr.getLocalizationFile(siteContext, + ARCHIVE_DIR + "/" + fileName); + lFile.delete(); + } + + /** + * Load the localized site select configuration file. + * + * @param fileName + * @return selectConfig + */ + public SelectConfig loadSelection(String fileName) { + SelectConfig selections = null; + LocalizationContext siteContext = pathMgr.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); + LocalizationFile lFile = pathMgr.getLocalizationFile(siteContext, + ARCHIVE_DIR + "/" + fileName); + if (lFile.exists()) { + FileInputStream stream = null; + try { + stream = lFile.openInputStream(); + selections = unmarshallSelectionStream(stream); + } catch (LocalizationException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } catch (IOException e) { + statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(), + e); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException ex) { + // Ignore + } + } + } + } + return selections; + } + + // TODO possible future methods for supporting importing and exporting + // select configurations. + // + // public SelectConfig importSelections(File selectFile) throws IOException + // { + // SelectConfig selections = null; + // FileInputStream stream = new FileInputStream(selectFile); + // selections = unmarshallSelectionStream(stream); + // return selections; + // } + // + // public boolean exportSelections(SelectConfig selections, File selectFile) + // throws IOException, LocalizationException { + // FileOutputStream stream = null; + // try { + // stream = new FileOutputStream(selectFile); + // marshalSelectStream(selections, stream); + // } finally { + // if (stream != null) { + // try { + // stream.close(); + // } catch (IOException ex) { + // // Ignore + // } + // } + // } + // return false; + // } + + /** + * Get a list of selection names based on the select configuration files in + * the type's directory. + * + * @param type + * @return selectNames + */ + public String[] getSelectionNames(ArchiveConstants.Type type) { + LocalizationFile[] files = pathMgr.listStaticFiles(ARCHIVE_DIR + + IPathManager.SEPARATOR + type.selectionDir, + new String[] { ArchiveConstants.configFileExt }, false, true); + String[] names = new String[files.length]; + int extLen = ArchiveConstants.configFileExt.length(); + int i = 0; + StringBuilder sb = new StringBuilder(); + for (LocalizationFile lFile : files) { + sb.setLength(0); + sb.append(lFile.getName()); + sb.setLength(sb.length() - extLen); + names[i] = sb.substring(sb.lastIndexOf(IPathManager.SEPARATOR) + 1); + ++i; + } + Arrays.sort(names, String.CASE_INSENSITIVE_ORDER); + return names; + } + + /** + * Save the selections configuration in the desired file. + * + * @param selections + * @param fileName + * @throws LocalizationException + * @throws IOException + */ + public void saveSelections(SelectConfig selections, String fileName) + throws LocalizationException, IOException { + LocalizationFileOutputStream stream = null; + LocalizationContext siteContext = pathMgr.getContext( + LocalizationType.COMMON_STATIC, LocalizationLevel.SITE); + LocalizationFile lFile = pathMgr.getLocalizationFile(siteContext, + ARCHIVE_DIR + IPathManager.SEPARATOR + fileName); + + try { + stream = lFile.openOutputStream(); + marshalSelectStream(selections, stream); + } finally { + if (stream != null) { + try { + stream.closeAndSave(); + } catch (Exception ex) { + // Ignore + } + } + } + } + + /** + * load select configuration from the stream. + * + * @param stream + * @return selectConfig + * @throws IOException + */ + private SelectConfig unmarshallSelectionStream(FileInputStream stream) + throws IOException { + SelectConfig selections = null; + try { + selections = JAXB.unmarshal(stream, SelectConfig.class); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException ex) { + // ignore + } + } + } + return selections; + } + + /** + * Save select configuration to the desired stream. + * + * @param selections + * @param stream + * @throws IOException + * @throws LocalizationException + */ + private void marshalSelectStream(SelectConfig selections, + FileOutputStream stream) throws IOException, LocalizationException { + JAXB.marshal(selections, stream); + } } diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConstants.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConstants.java new file mode 100644 index 0000000000..6389159ff7 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/ArchiveConstants.java @@ -0,0 +1,108 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.archive.config; + +import java.util.regex.Pattern; + +import com.raytheon.uf.common.localization.IPathManager; + +/** + * Constants used by purger and GUIs. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 23, 2013 #2221      rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class ArchiveConstants { + + /** Pattern to find slashes in a string. */ + private final static Pattern slashPattern = Pattern.compile("[/\\\\]+"); + + /** Pattern to find white space in a string. */ + private final static Pattern wsPattern = Pattern.compile("\\s+"); + + /** Default selection name to display. */ + public static final String defaultSelectName = "DEFAULT"; + + /** Extension to use for creating a configuration's file name. */ + public static final String configFileExt = ".xml"; + + /** Types of select configuration and their relative localized directory. */ + public enum Type { + Retention("retention" + IPathManager.SEPARATOR), Case("case" + + IPathManager.SEPARATOR); + + public final String selectionDir; + + private Type(String selectionDir) { + this.selectionDir = selectionDir; + } + } + + /** + * Do not allow an instance of this class. + */ + private ArchiveConstants() { + } + + /** + * Get relative path file name for a select configuration file based on type + * and name. + * + * @param type + * @param name + * - when null use the default select name. + * @return fileName + */ + public static final String selectFileName(Type type, String name) { + String fileName = name; + if (fileName == null) { + fileName = defaultSelectName; + } else { + fileName = convertToFileName(name); + } + return type.selectionDir + fileName + configFileExt; + } + + /** + * Convert name to fileName by trimming whitespace, converting slashes to + * hyphens and embedded whitespace to underscore. + * + * @param name + * - must not be null + * @return fileName + */ + public static final String convertToFileName(String name) { + String fileName = name.trim(); + fileName = slashPattern.matcher(fileName).replaceAll("-"); + fileName = wsPattern.matcher(fileName).replaceAll("_"); + return fileName; + } +} diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/SelectConfig.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/SelectConfig.java new file mode 100644 index 0000000000..babc5a51ae --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/SelectConfig.java @@ -0,0 +1,192 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.archive.config; + +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; + +import com.raytheon.uf.common.archive.config.select.ArchiveSelect; +import com.raytheon.uf.common.archive.config.select.CategorySelect; + +/** + * Select configuraton information for retention and case creation. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 19, 2013 2221       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "selection") +public class SelectConfig { + /** + * Name of selection. + */ + @XmlElement(name = "name") + private String name; + + /** + * Hours to back off Start time from the End time. + */ + @XmlElement(name = "startRetentionHours") + private long starRetentionHours = 24L; + + /** + * List of archives + */ + @XmlElement(name = "archive") + private final List archiveList = new ArrayList(); + + /** + * Constructor. + */ + public SelectConfig() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getStarRetentionHours() { + return starRetentionHours; + } + + public void setStarRetentionHours(long startRetentionHours) { + this.starRetentionHours = startRetentionHours; + } + + public List getArchiveList() { + return archiveList; + } + + public void setArchiveList(List archiveList) { + this.archiveList.clear(); + this.archiveList.addAll(archiveList); + } + + public void add(ArchiveSelect archiveSelect) { + archiveList.add(archiveSelect); + } + + /** + * + * @return true when no selections + */ + public boolean isEmpty() { + return archiveList.isEmpty(); + } + + /** + * Get a list of selected display names for the archive and its category. + * + * @param archiveName + * @param categoryName + * @return displayLabelList may be an empty list. + */ + public List getSelectedList(String archiveName, String categoryName) { + ArchiveSelect archiveSelect = getArchive(archiveName); + if (archiveSelect == null || archiveSelect.isEmpty()) { + return new ArrayList(0); + } + CategorySelect categorySelect = getCategorySelect(categoryName, + archiveSelect); + if (categorySelect == null || categorySelect.isEmpty()) { + return new ArrayList(0); + } + + List selected = categorySelect.getSelectList(); + + return selected; + } + + /** + * Find archive with given name + * + * @param archiveName + * @return archive select or null if none found. message + */ + private ArchiveSelect getArchive(String archiveName) { + if (!archiveList.isEmpty()) { + for (ArchiveSelect archiveSelect : archiveList) { + if (archiveName.equals(archiveSelect.getName())) { + return archiveSelect; + } + } + } + return null; + } + + /** + * Find category for the given name under the desired archive. + * + * @param categoryName + * @param archiveSelect + * @return categorySelect or null if none found + */ + private CategorySelect getCategorySelect(String categoryName, + ArchiveSelect archiveSelect) { + if (!archiveSelect.isEmpty()) { + for (CategorySelect categorySelect : archiveSelect + .getCategorySelectList()) { + if (categoryName.equals(categorySelect.getName())) { + return categorySelect; + } + } + } + return null; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("selectData [name: ").append(getName()); + sb.append(", startRetentionHours: ").append(getStarRetentionHours()); + sb.append("["); + for (ArchiveSelect archiveConfig : getArchiveList()) { + sb.append(archiveConfig).append(", "); + } + sb.append("]]"); + return sb.toString(); + } +} diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/ArchiveSelect.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/ArchiveSelect.java new file mode 100644 index 0000000000..3d339147f5 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/ArchiveSelect.java @@ -0,0 +1,104 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.archive.config.select; + +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; + +/** + * Select configuration archive information. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 19, 2013 2221       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "archive") +public class ArchiveSelect { + /** + * The archive name. + */ + @XmlElement(name = "name") + private String name; + + /** + * List of categories with selections. + */ + @XmlElement(name = "category") + private final List categorySelectList = new ArrayList(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getCategorySelectList() { + return categorySelectList; + } + + public void setCategorySelectList(List categorySelectList) { + this.categorySelectList.clear(); + this.categorySelectList.addAll(categorySelectList); + } + + public void add(CategorySelect categorySelect) { + categorySelectList.add(categorySelect); + } + + public boolean isEmpty() { + return categorySelectList.isEmpty(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Archive Select [name : ").append(getName()); + sb.append("["); + for (CategorySelect categorySelect : categorySelectList) { + sb.append(categorySelect).append(", "); + } + sb.append("]"); + return sb.toString(); + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/CategorySelect.java b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/CategorySelect.java new file mode 100644 index 0000000000..5d4d2c5ec0 --- /dev/null +++ b/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/config/select/CategorySelect.java @@ -0,0 +1,98 @@ +/** + * This software was developed and / or modified by Raytheon Company, + * pursuant to Contract DG133W-05-CQ-1067 with the US Government. + * + * U.S. EXPORT CONTROLLED TECHNICAL DATA + * This software product contains export-restricted data whose + * export/transfer/disclosure is restricted by U.S. law. Dissemination + * to non-U.S. persons whether in the United States or abroad requires + * an export license or other authorization. + * + * Contractor Name: Raytheon Company + * Contractor Address: 6825 Pine Street, Suite 340 + * Mail Stop B8 + * Omaha, NE 68106 + * 402.291.0100 + * + * See the AWIPS II Master Rights File ("Master Rights File.pdf") for + * further licensing information. + **/ +package com.raytheon.uf.common.archive.config.select; + +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; + +/** + * Select configuration class that contains a list of selected display labels + * for a given category. It is assumed this is associated with a given archive. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jul 19, 2013 2221       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +@XmlAccessorType(XmlAccessType.NONE) +@XmlRootElement(name = "archive") +public class CategorySelect { + /** + * The category name. + */ + @XmlElement(name = "name") + private String name; + + /** + * List of selected labels. + */ + @XmlElement(name = "selectedDisplayName") + private final List selectList = new ArrayList(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getSelectList() { + return selectList; + } + + public void setSelectList(List selectList) { + this.selectList.clear(); + this.selectList.addAll(selectList); + } + + public void add(String displayName) { + selectList.add(displayName); + } + + public boolean isEmpty() { + return selectList.isEmpty(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("CategorySelect [ name: ").append(getName()); + sb.append("[ "); + for (String select : getSelectList()) { + sb.append("\"").append(select).append("\", "); + } + sb.append("]"); + return sb.toString(); + } +} diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml index 91752e1a0c..7d6bc4cda1 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.nwsauth/utility/common_static/base/roles/userRoles.xml @@ -92,6 +92,8 @@ + + com.raytheon.localization.site/common_static/purge @@ -125,6 +127,8 @@ com.raytheon.localization.site/common_static/roles com.raytheon.localization.site/common_static/datadelivery com.raytheon.localization.site/common_static/archiver/purger + com.raytheon.localization.site/common_static/archiver/purger/retention + com.raytheon.localization.site/common_static/archiver/purger/case