mirror of
https://github.com/PAMGuard/PAMGuard.git
synced 2024-11-21 22:52:22 +00:00
Global metadata
Reorganised how global meta data for a PAMGuard dataset is managed by wrapping a nilus deployment object so that PAMGuard settings can serialise and unpack the xml version of a nilus Deployment object.
This commit is contained in:
parent
bafe93e7f5
commit
7721d7f1c0
@ -54,6 +54,7 @@ import fftManager.FFTDataUnit;
|
||||
import generalDatabase.DBControlUnit;
|
||||
import javafx.application.Platform;
|
||||
import javafx.stage.Stage;
|
||||
import metadata.MetaDataContol;
|
||||
import Array.ArrayManager;
|
||||
import PamController.command.MulticastController;
|
||||
import PamController.command.NetworkController;
|
||||
@ -450,6 +451,7 @@ public class PamController implements PamControllerInterface, PamSettings {
|
||||
System.out.println("");
|
||||
System.out.println("Note - ignore the following SLF4J warn/error messages, they are not applicable to this application");
|
||||
ArrayManager.getArrayManager(); // create the array manager so that it get's it's settings
|
||||
MetaDataContol.getMetaDataControl();
|
||||
|
||||
/**
|
||||
* Check for archived files and unpack automatically.
|
||||
|
@ -461,10 +461,10 @@ final public class PamModel implements PamModelInterface, PamSettings {
|
||||
mi.setMaxNumber(1);
|
||||
|
||||
|
||||
mi = PamModuleInfo.registerControlledUnit(MetaDataContol.class.getName(), MetaDataContol.unitType);
|
||||
mi.setToolTipText("Project Meta Data");
|
||||
mi.setModulesMenuGroup(utilitiesGroup);
|
||||
mi.setMaxNumber(1);
|
||||
// mi = PamModuleInfo.registerControlledUnit(MetaDataContol.class.getName(), MetaDataContol.unitType);
|
||||
// mi.setToolTipText("Project Meta Data");
|
||||
// mi.setModulesMenuGroup(utilitiesGroup);
|
||||
// mi.setMaxNumber(1);
|
||||
|
||||
if (isViewer) {
|
||||
mi = PamModuleInfo.registerControlledUnit(TethysControl.class.getName(), TethysControl.defaultName);
|
||||
|
@ -1,44 +1,99 @@
|
||||
package metadata;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JMenuItem;
|
||||
|
||||
import PamController.PamControlledUnit;
|
||||
import PamController.PamControlledUnitSettings;
|
||||
import PamController.PamController;
|
||||
import PamController.PamSettingManager;
|
||||
import PamController.PamSettings;
|
||||
import PamModel.parametermanager.ParameterSetManager;
|
||||
import generalDatabase.parameterstore.ParameterDatabaseStore;
|
||||
import metadata.deployment.DeploymentData;
|
||||
|
||||
public class MetaDataContol extends PamControlledUnit {
|
||||
/**
|
||||
* Class to handle Project MetaData. Am making this a PAMControlledUnit, but may never
|
||||
* register it with the model ? Will see what advantages and disadvantages there are.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class MetaDataContol extends PamControlledUnit implements PamSettings {
|
||||
|
||||
public static final String unitType = "Meta Data";
|
||||
|
||||
private DeploymentData deploymentData = new DeploymentData();
|
||||
private static MetaDataContol singleInstance;
|
||||
|
||||
private ParameterSetManager<DeploymentData> deploymentSetManager;
|
||||
private PamguardMetaData pamguardMetaData = new PamguardMetaData();
|
||||
|
||||
// private ParameterSetManager<DeploymentData> deploymentSetManager;
|
||||
|
||||
|
||||
public MetaDataContol(String unitName) {
|
||||
private MetaDataContol(String unitName) {
|
||||
super(unitType, unitName);
|
||||
deploymentSetManager = new ParameterSetManager<DeploymentData>(deploymentData, "Deployment Data");
|
||||
// deploymentSetManager = new ParameterSetManager<DeploymentData>(deploymentData, "Deployment Data");
|
||||
PamSettingManager.getInstance().registerSettings(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Easy getter for singleton MetaData controller.
|
||||
* @return meta data controller
|
||||
*/
|
||||
public static MetaDataContol getMetaDataControl() {
|
||||
if (singleInstance == null) {
|
||||
singleInstance = new MetaDataContol(unitType);
|
||||
// add this line to add it to the main modules list. Then it will get menu's, etc.
|
||||
PamController.getInstance().addControlledUnit(singleInstance);
|
||||
}
|
||||
return singleInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get PAMGuard Metadata. This contains a nilus Deployment object wrapped up
|
||||
* so that it can be serialised into other PAMGuard settings.
|
||||
* @return PAMGuard meta data
|
||||
*/
|
||||
public PamguardMetaData getMetaData() {
|
||||
return pamguardMetaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the meta data object.
|
||||
* @param metaData
|
||||
*/
|
||||
public void setMetaData(PamguardMetaData metaData) {
|
||||
this.pamguardMetaData = metaData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JMenuItem createFileMenu(JFrame parentFrame) {
|
||||
return deploymentSetManager.getMenuItem(parentFrame);
|
||||
public Serializable getSettingsReference() {
|
||||
pamguardMetaData.checkSerialisation();
|
||||
return pamguardMetaData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deploymentData
|
||||
*/
|
||||
public DeploymentData getDeploymentData() {
|
||||
return deploymentData;
|
||||
@Override
|
||||
public long getSettingsVersion() {
|
||||
return PamguardMetaData.serialVersionUID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deploymentData the deploymentData to set
|
||||
*/
|
||||
public void setDeploymentData(DeploymentData deploymentData) {
|
||||
this.deploymentData = deploymentData;
|
||||
@Override
|
||||
public boolean restoreSettings(PamControlledUnitSettings pamControlledUnitSettings) {
|
||||
Object obj = pamControlledUnitSettings.getSettings();
|
||||
if (obj instanceof PamguardMetaData) {
|
||||
pamguardMetaData = (PamguardMetaData) obj;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public JMenuItem createFileMenu(JFrame parentFrame) {
|
||||
// return deploymentSetManager.getMenuItem(parentFrame);
|
||||
//// return null;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
79
src/metadata/PamguardMetaData.java
Normal file
79
src/metadata/PamguardMetaData.java
Normal file
@ -0,0 +1,79 @@
|
||||
package metadata;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import PamUtils.LatLong;
|
||||
import nilus.Deployment;
|
||||
import nilus.Helper;
|
||||
import tethys.niluswraps.NilusSettingsWrapper;
|
||||
|
||||
/**
|
||||
* Meta data for a PAMGuard data set. This is based around serialisable versions of
|
||||
* nilus classes to be compliant with both Tethys and PAMGuard settings files. May only
|
||||
* need a Deployment object, but scope for adding others / other fields if it's useful.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class PamguardMetaData implements Serializable {
|
||||
|
||||
public static final long serialVersionUID = 1L;
|
||||
|
||||
private NilusSettingsWrapper<Deployment> deploymentWrapper;
|
||||
|
||||
// /**
|
||||
// * Deployment time (used if different
|
||||
// */
|
||||
// private Long deploymentMillis;
|
||||
//
|
||||
// private Long recoverMillis;
|
||||
//
|
||||
// private LatLong recoverLatLong;
|
||||
|
||||
/**
|
||||
* Get the deployment data
|
||||
* @return nilus deployment
|
||||
*/
|
||||
public Deployment getDeployment() {
|
||||
if (deploymentWrapper == null) {
|
||||
deploymentWrapper = new NilusSettingsWrapper<>();
|
||||
}
|
||||
Deployment deployment = deploymentWrapper.getNilusObject(Deployment.class);
|
||||
if (deployment == null) {
|
||||
deployment = new Deployment();
|
||||
try {
|
||||
Helper.createRequiredElements(deployment);
|
||||
} catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
deploymentWrapper.setNilusObject(deployment);
|
||||
}
|
||||
return deploymentWrapper.getNilusObject(Deployment.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the deployment data.
|
||||
* @param deployment nilus deployment
|
||||
*/
|
||||
public void setDeployment(Deployment deployment) {
|
||||
if (deploymentWrapper == null) {
|
||||
deploymentWrapper = new NilusSettingsWrapper<>();
|
||||
}
|
||||
deploymentWrapper.setNilusObject(deployment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deploymentWrapper
|
||||
*/
|
||||
public NilusSettingsWrapper<Deployment> getDeploymentWrapper() {
|
||||
return deploymentWrapper;
|
||||
}
|
||||
|
||||
public void checkSerialisation() {
|
||||
// check that all wrappers have their xml up to date.
|
||||
deploymentWrapper.reSerialise();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -11,7 +11,8 @@ import PamUtils.LatLong;
|
||||
/**
|
||||
* Class to hold Deployment data in a form consistent with the ANSI PAM
|
||||
* Standard. This has been keep separate from the Tethys Interface to keep it
|
||||
* easy to benefit from these data without using Tethys itself.
|
||||
* easy to benefit from these data without using Tethys itself. Is also serilaisable
|
||||
* which is important for storage into PAMGuard settings.
|
||||
*
|
||||
* @author dg50
|
||||
*
|
||||
@ -108,15 +109,17 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
|
||||
this.recoveryMillis = recoveryMillis;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Instrument type, e.g. HARP, EAR, Popup, DMON, etc.
|
||||
// */
|
||||
// private String instrumentType;
|
||||
//
|
||||
// /**
|
||||
// * Instrument identifier, e.g. serial number
|
||||
// */
|
||||
// private String instrumentId;
|
||||
/**
|
||||
* Set data from a nilus deployment class
|
||||
* @param nilusDeployment
|
||||
*/
|
||||
public void setData(nilus.Deployment nilusDeployment) {
|
||||
|
||||
}
|
||||
|
||||
public void getData(nilus.Deployment nilusDeployment) {
|
||||
|
||||
}
|
||||
|
||||
public DeploymentData() {
|
||||
}
|
||||
@ -151,103 +154,103 @@ public class DeploymentData implements Serializable, Cloneable, ManagedParameter
|
||||
return ps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the project
|
||||
*/
|
||||
public String getProject() {
|
||||
return project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param project the project to set
|
||||
*/
|
||||
public void setProject(String project) {
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deploymentId
|
||||
*/
|
||||
public int getDeploymentId() {
|
||||
return deploymentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deploymentId the deploymentId to set
|
||||
*/
|
||||
public void setDeploymentId(int deploymentId) {
|
||||
this.deploymentId = deploymentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the deplomentAlias
|
||||
*/
|
||||
public String getDeploymentAlias() {
|
||||
return deploymentAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param deplomentAlias the deplomentAlias to set
|
||||
*/
|
||||
public void setDeploymentAlias(String deplomentAlias) {
|
||||
this.deploymentAlias = deplomentAlias;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the site
|
||||
*/
|
||||
public String getSite() {
|
||||
return site;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param site the site to set
|
||||
*/
|
||||
public void setSite(String site) {
|
||||
this.site = site;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the siteAliases
|
||||
*/
|
||||
public String getSiteAliases() {
|
||||
return siteAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param siteAliases the siteAliases to set
|
||||
*/
|
||||
public void setSiteAliases(String siteAliases) {
|
||||
this.siteAliases = siteAliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the cruise
|
||||
*/
|
||||
public String getCruise() {
|
||||
return cruise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cruise the cruise to set
|
||||
*/
|
||||
public void setCruise(String cruise) {
|
||||
this.cruise = cruise;
|
||||
}
|
||||
// /**
|
||||
// * @return the id
|
||||
// */
|
||||
// public String getId() {
|
||||
// return id;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param id the id to set
|
||||
// */
|
||||
// public void setId(String id) {
|
||||
// this.id = id;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the project
|
||||
// */
|
||||
// public String getProject() {
|
||||
// return project;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param project the project to set
|
||||
// */
|
||||
// public void setProject(String project) {
|
||||
// this.project = project;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the deploymentId
|
||||
// */
|
||||
// public int getDeploymentId() {
|
||||
// return deploymentId;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param deploymentId the deploymentId to set
|
||||
// */
|
||||
// public void setDeploymentId(int deploymentId) {
|
||||
// this.deploymentId = deploymentId;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the deplomentAlias
|
||||
// */
|
||||
// public String getDeploymentAlias() {
|
||||
// return deploymentAlias;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param deplomentAlias the deplomentAlias to set
|
||||
// */
|
||||
// public void setDeploymentAlias(String deplomentAlias) {
|
||||
// this.deploymentAlias = deplomentAlias;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the site
|
||||
// */
|
||||
// public String getSite() {
|
||||
// return site;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param site the site to set
|
||||
// */
|
||||
// public void setSite(String site) {
|
||||
// this.site = site;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the siteAliases
|
||||
// */
|
||||
// public String getSiteAliases() {
|
||||
// return siteAliases;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param siteAliases the siteAliases to set
|
||||
// */
|
||||
// public void setSiteAliases(String siteAliases) {
|
||||
// this.siteAliases = siteAliases;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @return the cruise
|
||||
// */
|
||||
// public String getCruise() {
|
||||
// return cruise;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * @param cruise the cruise to set
|
||||
// */
|
||||
// public void setCruise(String cruise) {
|
||||
// this.cruise = cruise;
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * @return the platform
|
||||
|
@ -36,7 +36,9 @@ import PamView.PamTabPanel;
|
||||
import PamView.dialog.warn.WarnOnce;
|
||||
import PamguardMVC.PamDataBlock;
|
||||
import metadata.MetaDataContol;
|
||||
import metadata.PamguardMetaData;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Deployment;
|
||||
import tethys.TethysState.StateType;
|
||||
import tethys.calibration.CalibrationHandler;
|
||||
import tethys.dbxml.DBXMLConnect;
|
||||
@ -406,31 +408,23 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
|
||||
* so that the rest of PAMGuard can use it, but creating the
|
||||
* @return
|
||||
*/
|
||||
public DeploymentData getGlobalDeplopymentData() {
|
||||
PamControlledUnit aUnit = PamController.getInstance().findControlledUnit(MetaDataContol.class, null);
|
||||
// if (aUnit instanceof MetaDataContol == false || true) {
|
||||
// deployment.setProject("thisIsAProject");
|
||||
// deployment.setPlatform("Yay a platform");
|
||||
// Instrument instrument = new Instrument();
|
||||
// instrument.setType("machiney");
|
||||
// instrument.setInstrumentId("12345555");
|
||||
// deployment.setInstrument(instrument);
|
||||
// return false;
|
||||
// }
|
||||
public Deployment getGlobalDeplopymentData() {
|
||||
|
||||
MetaDataContol metaControl = (MetaDataContol) aUnit;
|
||||
DeploymentData deploymentData = metaControl != null ? metaControl.getDeploymentData() : getTethysProjectData();
|
||||
|
||||
// deploymentData.setProject("thisIsAProject");
|
||||
//// deploymentData.setPlatform("Yay a platform");
|
||||
// deploymentData.setCruise("cruisey");
|
||||
// deploymentData.setDeploymentId(142536);
|
||||
//// deploymentData.setInstrumentId("super instrument");
|
||||
// deploymentData.setSite("in the ocean somewhere");
|
||||
// deploymentData.setRegion("ocean water");
|
||||
//// deploymentData.setInstrumentType("sensor of sorts");
|
||||
|
||||
return deploymentData;
|
||||
MetaDataContol metaControl = MetaDataContol.getMetaDataControl();
|
||||
PamguardMetaData metaData = metaControl.getMetaData();
|
||||
return metaData.getDeployment();
|
||||
// Deployment deploymentData = metaControl != null ? metaData.getDeployment() : getTethysProjectData();
|
||||
//
|
||||
//// deploymentData.setProject("thisIsAProject");
|
||||
////// deploymentData.setPlatform("Yay a platform");
|
||||
//// deploymentData.setCruise("cruisey");
|
||||
//// deploymentData.setDeploymentId(142536);
|
||||
////// deploymentData.setInstrumentId("super instrument");
|
||||
//// deploymentData.setSite("in the ocean somewhere");
|
||||
//// deploymentData.setRegion("ocean water");
|
||||
////// deploymentData.setInstrumentType("sensor of sorts");
|
||||
//
|
||||
// return deploymentData;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -545,7 +539,7 @@ public class TethysControl extends PamControlledUnit implements PamSettings, Tet
|
||||
if (dataBlockSynchInfos == null) {
|
||||
return;
|
||||
}
|
||||
DeploymentData deplData = getGlobalDeplopymentData();
|
||||
Deployment deplData = getGlobalDeplopymentData();
|
||||
String[] dataPrefixes = new String[dataBlockSynchInfos.size()];
|
||||
int i = 0;
|
||||
ArrayList<PDeployment> matchedDeployments = deploymentHandler.getMatchedDeployments();
|
||||
|
@ -4,7 +4,6 @@ import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@ -116,9 +115,14 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
* Update the list of documents associated with the selected instrument.
|
||||
*/
|
||||
private void updateDocumentsList() {
|
||||
|
||||
calibrationsList.clear();
|
||||
|
||||
ArrayList<DocumentInfo> docsList = getArrayCalibrations();
|
||||
// now immediately read the calibrations in again.
|
||||
calibrationsList.clear();;
|
||||
if (docsList == null) {
|
||||
return;
|
||||
}
|
||||
NilusUnpacker unpacker = new NilusUnpacker();
|
||||
for (DocumentInfo aDoc : docsList) {
|
||||
Queries queries = tethysControl.getDbxmlConnect().getTethysQueries();
|
||||
@ -182,11 +186,7 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
// String docName = getHydrophoneId(i);
|
||||
Calibration calDoc = createCalibrationDocument(i);
|
||||
if (sampleCal != null) {
|
||||
calDoc.setMetadataInfo(sampleCal.getMetadataInfo());
|
||||
MetadataInfo oldMeta = calDoc.getMetadataInfo();
|
||||
MetadataInfo newMeta = sampleCal.getMetadataInfo();
|
||||
|
||||
|
||||
calDoc.setMetadataInfo(sampleCal.getMetadataInfo());
|
||||
calDoc.setProcess(sampleCal.getProcess());
|
||||
calDoc.setQualityAssurance(sampleCal.getQualityAssurance());
|
||||
calDoc.setResponsibleParty(sampleCal.getResponsibleParty());
|
||||
@ -234,7 +234,7 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
* Add the separate pamguard parameters to the document which are used
|
||||
* to make up the overall calibration.
|
||||
* @param calDoc
|
||||
* @param i
|
||||
* @param i hydrophone number
|
||||
*/
|
||||
private void addParameterDetails(Calibration calDoc, int i) {
|
||||
Parameters params = calDoc.getProcess().getParameters();
|
||||
@ -518,8 +518,10 @@ public class CalibrationHandler implements TethysStateObserver {
|
||||
*/
|
||||
private ArrayList<DocumentInfo> getArrayCalibrations() {
|
||||
ArrayList<DocumentInfo> allCals = tethysControl.getDbxmlQueries().getCollectionDocumentList(Collection.Calibrations);
|
||||
String prefix = createCalibrationDocumentRoot();
|
||||
// find doc names that have that root.
|
||||
if (allCals == null) {
|
||||
return null;
|
||||
}
|
||||
String prefix = createCalibrationDocumentRoot(); // find doc names that have that root.
|
||||
ArrayList<DocumentInfo> theseCals = new ArrayList<>();
|
||||
for (DocumentInfo aDoc : allCals) {
|
||||
if (aDoc.getDocumentName().startsWith(prefix)) {
|
||||
|
@ -78,9 +78,11 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
||||
c.gridwidth = 1;
|
||||
processPanel.add(new JLabel("Serial number ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
c.gridwidth = 2;
|
||||
processPanel.add(version, c);
|
||||
c.gridx = 0;
|
||||
c.gridy++;
|
||||
c.gridwidth = 1;
|
||||
processPanel.add(new JLabel("Quality ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
processPanel.add(qaQuality, c);
|
||||
@ -88,6 +90,7 @@ public class CalibrationProcessCard extends CalibrationsCard {
|
||||
c.gridy++;
|
||||
processPanel.add(new JLabel("QA Comment ", JLabel.RIGHT), c);
|
||||
c.gridx++;
|
||||
c.gridwidth = 2;
|
||||
processPanel.add(qaComment, c);
|
||||
|
||||
this.add(BorderLayout.CENTER, makeScrollablePanel(software, "Calibration method"));
|
||||
|
@ -9,6 +9,7 @@ import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.datatype.XMLGregorianCalendar;
|
||||
|
||||
import org.apache.commons.beanutils.converters.BigIntegerConverter;
|
||||
|
||||
@ -34,6 +35,8 @@ import binaryFileStorage.BinaryStore;
|
||||
import dataMap.OfflineDataMap;
|
||||
import dataMap.OfflineDataMapPoint;
|
||||
import generalDatabase.DBControlUnit;
|
||||
import metadata.MetaDataContol;
|
||||
import metadata.PamguardMetaData;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Audio;
|
||||
import nilus.ChannelInfo;
|
||||
@ -125,7 +128,7 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
* @return true if OK
|
||||
*/
|
||||
public boolean updateProjectDeployments() {
|
||||
DeploymentData projData = tethysControl.getGlobalDeplopymentData();
|
||||
Deployment projData = tethysControl.getGlobalDeplopymentData();
|
||||
ArrayList<Deployment> tethysDocs = tethysControl.getDbxmlQueries().getProjectDeployments(projData.getProject(), getInstrumentId());
|
||||
if (tethysDocs == null) {
|
||||
return false;
|
||||
@ -310,7 +313,7 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
selectedDeployments.get(selectedDeployments.size()-1).getRecordStop());
|
||||
Deployment deployment = createDeploymentDocument(freeId, onePeriod);
|
||||
// fill in a few things from here
|
||||
DeploymentData globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
Deployment globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
deployment.setCruise(globalMeta.getCruise());
|
||||
deployment.setSite(globalMeta.getSite());
|
||||
if (selectedDeployments.size() > 1) {
|
||||
@ -344,6 +347,8 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
private void exportSeparateDeployments(ArrayList<RecordingPeriod> selectedDeployments) {
|
||||
|
||||
int freeId = getTethysControl().getDeploymentHandler().getFirstFreeDeploymentId();
|
||||
// fill in a few things from here
|
||||
Deployment globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
for (int i = 0; i < selectedDeployments.size(); i++) {
|
||||
RecordingPeriod recordPeriod = selectedDeployments.get(i);
|
||||
PDeployment exDeploymnet = recordPeriod.getMatchedTethysDeployment();
|
||||
@ -355,8 +360,6 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
if (deployment == null) {
|
||||
deployment = createDeploymentDocument(freeId++, recordPeriod);
|
||||
}
|
||||
// fill in a few things from here
|
||||
DeploymentData globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
deployment.setCruise(globalMeta.getCruise());
|
||||
deployment.setSite(globalMeta.getSite());
|
||||
// also need to sort out track data here, etc.
|
||||
@ -740,7 +743,7 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
DeploymentData globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
// Deployment globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
TethysExportParams exportParams = tethysControl.getTethysExportParams();
|
||||
String id = String.format("%s_%d", exportParams.getDatasetName(), i);
|
||||
deployment.setId(id);
|
||||
@ -903,7 +906,8 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
// }
|
||||
//
|
||||
// MetaDataContol metaControl = (MetaDataContol) aUnit;
|
||||
DeploymentData deploymentData = tethysControl.getGlobalDeplopymentData();
|
||||
PamguardMetaData metaData = MetaDataContol.getMetaDataControl().getMetaData();
|
||||
Deployment deploymentData = tethysControl.getGlobalDeplopymentData();
|
||||
deployment.setProject(deploymentData.getProject());
|
||||
deployment.setDeploymentAlias(deploymentData.getDeploymentAlias());
|
||||
deployment.setSite(deploymentData.getSite());
|
||||
@ -919,18 +923,19 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
deployment.setInstrument(instrument);
|
||||
|
||||
// overwrite the default deployment and recovery times if there is non null data
|
||||
Long depMillis = deploymentData.getDeploymentMillis();
|
||||
if (depMillis != null) {
|
||||
deployment.getDeploymentDetails().setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(depMillis));
|
||||
XMLGregorianCalendar depTime = deploymentData.getDeploymentDetails().getTimeStamp();
|
||||
if (depTime != null) {
|
||||
deployment.getDeploymentDetails().setTimeStamp(depTime);
|
||||
}
|
||||
Long recMillis = deploymentData.getRecoveryMillis();
|
||||
XMLGregorianCalendar recMillis = deploymentData.getRecoveryDetails().getTimeStamp();
|
||||
if (recMillis != null) {
|
||||
deployment.getRecoveryDetails().setTimeStamp(TethysTimeFuncs.xmlGregCalFromMillis(recMillis));
|
||||
deployment.getRecoveryDetails().setTimeStamp(recMillis);
|
||||
}
|
||||
LatLong recLatLong = deploymentData.getRecoverLatLong();
|
||||
if (recLatLong != null) {
|
||||
deployment.getRecoveryDetails().setLatitude(recLatLong.getLatitude());
|
||||
deployment.getRecoveryDetails().setLongitude(PamUtils.constrainedAngle(recLatLong.getLongitude()));
|
||||
double recLat = deploymentData.getRecoveryDetails().getLatitude();
|
||||
double recLong = deploymentData.getRecoveryDetails().getLongitude();
|
||||
if (recLat != 0 & recLong != 0.) {
|
||||
deployment.getRecoveryDetails().setLatitude(recLat);
|
||||
deployment.getRecoveryDetails().setLongitude(PamUtils.constrainedAngle(recLong));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -951,7 +956,7 @@ public class DeploymentHandler implements TethysStateObserver {
|
||||
*/
|
||||
public String canExportDeployments() {
|
||||
|
||||
DeploymentData globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
Deployment globalDeplData = tethysControl.getGlobalDeplopymentData();
|
||||
if (globalDeplData.getProject() == null) {
|
||||
return "You must set a project name";
|
||||
}
|
||||
|
196
src/tethys/niluswraps/NilusSettingsWrapper.java
Normal file
196
src/tethys/niluswraps/NilusSettingsWrapper.java
Normal file
@ -0,0 +1,196 @@
|
||||
package tethys.niluswraps;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringReader;
|
||||
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import nilus.MarshalXML;
|
||||
|
||||
/**
|
||||
* Class to wrap up a nilus object so that it can be saved using Java serialization.
|
||||
* This is basically saving the xml as a String, since all nilus objects are NOT
|
||||
* serializable, but should make it (relatively) straight forward to save nilus
|
||||
* objects into PAMGuard settings files.
|
||||
* @author dg50
|
||||
*
|
||||
*/
|
||||
public class NilusSettingsWrapper<T extends Object> implements Serializable, Cloneable {
|
||||
|
||||
public static final long serialVersionUID = 1L;
|
||||
|
||||
private String xmlString;
|
||||
|
||||
private transient T nilusObject;
|
||||
|
||||
/**
|
||||
* Create a nilus object. Have to pass the class type in as
|
||||
* an argument, since Class isn't serializable, so can't be stored
|
||||
* with the object - which contains nothing but a String, which can be safely serialised.
|
||||
* @param nilusClass
|
||||
* @return nilus object.
|
||||
*/
|
||||
public T getNilusObject(Class nilusClass) {
|
||||
if (nilusObject == null) {
|
||||
nilusObject = unpackNilusObject(nilusClass);
|
||||
}
|
||||
return nilusObject;
|
||||
}
|
||||
|
||||
private T unpackNilusObject(Class nilusClass) {
|
||||
Document doc = getDocument();
|
||||
if (doc == null) {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Try to turn the string into a document.
|
||||
*/
|
||||
NilusUnpacker unpacker = new NilusUnpacker();
|
||||
T unpacked = (T) unpacker.unpackDocument(doc, nilusClass);
|
||||
|
||||
return unpacked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the nilus object. This marshals the nilus object
|
||||
* into xml and saves the data as an intetnal xml string which
|
||||
* can be safely serialized.
|
||||
* @param nilusObject nilus object.
|
||||
* @return true if it was marshalled OK.
|
||||
*/
|
||||
public boolean setNilusObject(T nilusObject) {
|
||||
// use the marshaller to create a Tethys type document, then
|
||||
// get it as a string.
|
||||
this.nilusObject = nilusObject;
|
||||
// and convert immediately to the XML string.
|
||||
return packNilusObject(nilusObject);
|
||||
}
|
||||
/**
|
||||
* Set the nilus object. This marshals the nilus object
|
||||
* into xml and saves the data as an intetnal xml string which
|
||||
* can be safely serialized.
|
||||
* @param nilusObject nilus object.
|
||||
* @return true if it was marshalled OK.
|
||||
*/
|
||||
private boolean packNilusObject(T nilusObject) {
|
||||
// use the marshaller to create a Tethys type document, then
|
||||
// get it as a string.
|
||||
// and convert immediately to XML string.
|
||||
if (nilusObject == null) {
|
||||
xmlString = null;
|
||||
return true;
|
||||
}
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
PrintWriter printWriter = new PrintWriter(bos);
|
||||
MarshalXML marshaler;
|
||||
try {
|
||||
marshaler = new MarshalXML();
|
||||
marshaler.marshal(nilusObject, bos);
|
||||
} catch (JAXBException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
xmlString = bos.toString();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repack the object. May want to do this before serializing.
|
||||
* @return
|
||||
*/
|
||||
public boolean repackNilusObject() {
|
||||
return packNilusObject(nilusObject);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a document from the internal xml String representation.
|
||||
* @return xml document
|
||||
*/
|
||||
public Document getDocument() {
|
||||
if(xmlString == null) {
|
||||
return null;
|
||||
}
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
//API to obtain DOM Document instance
|
||||
DocumentBuilder builder = null;
|
||||
try {
|
||||
//Create DocumentBuilder with default configuration
|
||||
builder = factory.newDocumentBuilder();
|
||||
//Parse the content to Document object
|
||||
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
|
||||
return doc;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the xmlString
|
||||
*/
|
||||
public String getXmlString() {
|
||||
return xmlString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repack the nilus object. Call this just before settings are
|
||||
* saved to ensure everything is up to date since this probably won't
|
||||
* have happened if changes were made within existing nilus objects
|
||||
* and setNilusObject was never called.
|
||||
*/
|
||||
public void reSerialise() {
|
||||
packNilusObject(nilusObject);
|
||||
}
|
||||
|
||||
|
||||
// private Class<?> getNilusClass() throws NoSuchMethodException, SecurityException {
|
||||
// Method method = this.getClass().getMethod("getNilusObject", null);
|
||||
// Class<?> retClass = GenericTypeResolver.resolveReturnType(method, this.getClass());
|
||||
//
|
||||
// return retClass;
|
||||
// }
|
||||
|
||||
//
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// Deployment deployment = new Deployment();
|
||||
// try {
|
||||
// Helper.createRequiredElements(deployment);
|
||||
// } catch (IllegalArgumentException | IllegalAccessException | InstantiationException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// deployment.setCruise("Test cruise");
|
||||
// deployment.setDeploymentId(111);
|
||||
// deployment.setProject("Tethys Development");
|
||||
// DescriptionType desc = deployment.getDescription();
|
||||
// if (desc == null) {
|
||||
// desc = new DescriptionType();
|
||||
// deployment.setDescription(desc);
|
||||
// }
|
||||
// desc.setAbstract("Deployment Abstract");
|
||||
//
|
||||
// NilusSettingsWrapper<Deployment> wrapper = new NilusSettingsWrapper<>();
|
||||
//
|
||||
// wrapper.setNilusObject(deployment);
|
||||
//
|
||||
// System.out.println(wrapper.xmlString);
|
||||
//
|
||||
// Deployment newDeployment = wrapper.getNilusObject(Deployment.class);
|
||||
//
|
||||
// // now warp the new object again and print that.
|
||||
// newDeployment.setDeploymentId(newDeployment.getDeploymentId()*2);
|
||||
// wrapper.setNilusObject(newDeployment);
|
||||
// System.out.println("********************************************");
|
||||
// System.out.println(wrapper.xmlString);
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
@ -210,26 +210,26 @@ public class TethysExporter {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* find Deployment data. This is stored in a separate PAMGuard module, which may
|
||||
* not be present.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public DeploymentData findDeploymentData() {
|
||||
/**
|
||||
* What to do if this isn't present or is incomplete ? Should we be showing this
|
||||
* in the main export dialog at some point ? More a Q for when we make a nicer
|
||||
* UI later in the project.
|
||||
*/
|
||||
MetaDataContol metaControl = (MetaDataContol) PamController.getInstance()
|
||||
.findControlledUnit(MetaDataContol.unitType);
|
||||
if (metaControl == null) {
|
||||
return null;
|
||||
} else {
|
||||
return metaControl.getDeploymentData();
|
||||
}
|
||||
}
|
||||
// /**
|
||||
// * find Deployment data. This is stored in a separate PAMGuard module, which may
|
||||
// * not be present.
|
||||
// *
|
||||
// * @return
|
||||
// */
|
||||
// public DeploymentData findDeploymentData() {
|
||||
// /**
|
||||
// * What to do if this isn't present or is incomplete ? Should we be showing this
|
||||
// * in the main export dialog at some point ? More a Q for when we make a nicer
|
||||
// * UI later in the project.
|
||||
// */
|
||||
// MetaDataContol metaControl = (MetaDataContol) PamController.getInstance()
|
||||
// .findControlledUnit(MetaDataContol.unitType);
|
||||
// if (metaControl == null) {
|
||||
// return null;
|
||||
// } else {
|
||||
// return metaControl.getDeploymentData();
|
||||
// }
|
||||
// }
|
||||
|
||||
public SnapshotGeometry findArrayGeometrey() {
|
||||
/*
|
||||
|
@ -132,7 +132,7 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
|
||||
}
|
||||
|
||||
private void copyDeploymentData(Deployment deployment) {
|
||||
DeploymentData globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
Deployment globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
globalMeta.setSite(deployment.getSite());
|
||||
globalMeta.setCruise(deployment.getCruise());
|
||||
globalMeta.setRegion(deployment.getRegion());
|
||||
@ -189,7 +189,7 @@ public class DeploymentExportPanel extends TethysGUIPanel implements DeploymentT
|
||||
* Set the parms from internally stored data.
|
||||
*/
|
||||
private void setInternal() {
|
||||
DeploymentData globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
Deployment globalMeta = getTethysControl().getGlobalDeplopymentData();
|
||||
site.setText(globalMeta.getSite());
|
||||
cruise.setText(globalMeta.getCruise());
|
||||
// region.setText(globalMeta.getRegion());
|
||||
|
@ -10,7 +10,9 @@ import javax.swing.JTextField;
|
||||
import javax.swing.border.TitledBorder;
|
||||
|
||||
import PamView.dialog.PamGridBagContraints;
|
||||
import metadata.PamguardMetaData;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Deployment;
|
||||
import tethys.TethysControl;
|
||||
|
||||
public class NewProjectDialog extends PamView.dialog.PamDialog {
|
||||
@ -23,7 +25,7 @@ public class NewProjectDialog extends PamView.dialog.PamDialog {
|
||||
|
||||
private JTextField projectRegion;
|
||||
|
||||
private DeploymentData deploymentData;
|
||||
private PamguardMetaData metaData;
|
||||
|
||||
private NewProjectDialog(Window parentFrame, TethysControl tethysControl) {
|
||||
super(parentFrame, "New Project", false);
|
||||
@ -45,32 +47,33 @@ public class NewProjectDialog extends PamView.dialog.PamDialog {
|
||||
setDialogComponent(mainPanel);
|
||||
}
|
||||
|
||||
public static DeploymentData showDialog(Window parent, TethysControl tethysControl, DeploymentData deploymentData) {
|
||||
public static PamguardMetaData showDialog(Window parent, TethysControl tethysControl, PamguardMetaData metaData) {
|
||||
if (singleInstance == null) {
|
||||
singleInstance = new NewProjectDialog(parent, tethysControl);
|
||||
}
|
||||
singleInstance.setParams(deploymentData);
|
||||
singleInstance.setParams(metaData);
|
||||
singleInstance.setVisible(true);
|
||||
return singleInstance.deploymentData;
|
||||
return singleInstance.metaData;
|
||||
}
|
||||
|
||||
private void setParams(DeploymentData deploymentData) {
|
||||
private void setParams(PamguardMetaData deploymentData) {
|
||||
if (deploymentData == null) {
|
||||
return;
|
||||
}
|
||||
this.deploymentData = deploymentData;
|
||||
projectName.setText(deploymentData.getProject());
|
||||
projectRegion.setText(deploymentData.getRegion());
|
||||
this.metaData = deploymentData;
|
||||
projectName.setText(deploymentData.getDeployment().getProject());
|
||||
projectRegion.setText(deploymentData.getDeployment().getRegion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getParams() {
|
||||
if (deploymentData == null) {
|
||||
if (metaData == null) {
|
||||
return false;
|
||||
}
|
||||
deploymentData.setProject(projectName.getText());
|
||||
deploymentData.setRegion(projectRegion.getText());
|
||||
if (deploymentData.getProject() == null || deploymentData.getProject().length() == 0) {
|
||||
Deployment deployment = metaData.getDeployment();
|
||||
deployment.setProject(projectName.getText());
|
||||
deployment.setRegion(projectRegion.getText());
|
||||
if (deployment.getProject() == null || deployment.getProject().length() == 0) {
|
||||
return showWarning("you must specify a project name");
|
||||
}
|
||||
|
||||
@ -79,7 +82,7 @@ public class NewProjectDialog extends PamView.dialog.PamDialog {
|
||||
|
||||
@Override
|
||||
public void cancelButtonPressed() {
|
||||
deploymentData = null;
|
||||
metaData = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -22,6 +22,8 @@ import PamView.dialog.ScrollingPamLabel;
|
||||
import PamView.dialog.SettingsButton;
|
||||
import PamView.panel.PamPanel;
|
||||
import PamView.panel.WestAlignedPanel;
|
||||
import metadata.MetaDataContol;
|
||||
import metadata.PamguardMetaData;
|
||||
import metadata.deployment.DeploymentData;
|
||||
import nilus.Deployment;
|
||||
import pamViewFX.fxNodes.PamComboBox;
|
||||
@ -185,9 +187,10 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
* Action from new project button
|
||||
*/
|
||||
protected void createNewProject() {
|
||||
DeploymentData pamDeploymentData = getTethysControl().getGlobalDeplopymentData();
|
||||
PamguardMetaData pamDeploymentData = MetaDataContol.getMetaDataControl().getMetaData();
|
||||
pamDeploymentData = NewProjectDialog.showDialog(getTethysControl().getGuiFrame(), getTethysControl(), pamDeploymentData);
|
||||
if (pamDeploymentData != null) {
|
||||
MetaDataContol.getMetaDataControl().setMetaData(pamDeploymentData);
|
||||
updateProjectList();
|
||||
}
|
||||
}
|
||||
@ -197,8 +200,10 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
DeploymentData globData = getTethysControl().getGlobalDeplopymentData();
|
||||
globData.setProject(project);
|
||||
PamguardMetaData pamMetaData = MetaDataContol.getMetaDataControl().getMetaData();
|
||||
Deployment globDeployment = pamMetaData.getDeployment();
|
||||
// DeploymentData globData = getTethysControl().getGlobalDeplopymentData();
|
||||
globDeployment.setProject(project);
|
||||
getTethysControl().getDeploymentHandler().updateProjectDeployments();
|
||||
/*
|
||||
* if there are existing deployment data, then copy the info to the
|
||||
@ -207,8 +212,8 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
ArrayList<PDeployment> projectDeployments = getTethysControl().getDeploymentHandler().getProjectDeployments();
|
||||
if (projectDeployments != null && projectDeployments.size() > 0) {
|
||||
Deployment dep = projectDeployments.get(0).deployment;
|
||||
globData.setProject(dep.getProject());
|
||||
globData.setRegion(dep.getRegion());
|
||||
globDeployment.setProject(dep.getProject());
|
||||
globDeployment.setRegion(dep.getRegion());
|
||||
getTethysControl().sendStateUpdate(new TethysState(TethysState.StateType.NEWPROJECTSELECTION));
|
||||
}
|
||||
|
||||
@ -271,9 +276,10 @@ public class TethysConnectionPanel extends TethysGUIPanel {
|
||||
* list.
|
||||
*/
|
||||
String localProjName = null;
|
||||
DeploymentData pamDeploymentData = getTethysControl().getGlobalDeplopymentData();
|
||||
if (pamDeploymentData != null && pamDeploymentData.getProject() != null) {
|
||||
localProjName = pamDeploymentData.getProject();
|
||||
PamguardMetaData pamMetaData = MetaDataContol.getMetaDataControl().getMetaData();
|
||||
Deployment globDeployment = pamMetaData.getDeployment();
|
||||
if (globDeployment != null && globDeployment.getProject() != null) {
|
||||
localProjName = globDeployment.getProject();
|
||||
if (localProjName.length() == 0) {
|
||||
localProjName = null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user