package no.met.metadataeditor.widget;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import no.met.metadataeditor.Config;
import no.met.metadataeditor.EditorWidgetView;
import no.met.metadataeditor.InvalidEditorConfigurationException;
import no.met.metadataeditor.dataTypes.EditorVariableContent;
import no.met.metadataeditor.dataTypes.attributes.StringAttribute;
/**
* Widget used for the creation of the Met.no dataset identifiers.
*
* At Met.no metadata can for a dataset can be generated using several
* different method, only one of them being the metadata editor. Since
* there are no central control for controlling the uniqueness of an
* identifier each system cabable of generating a new identifier is
* given a unique generator id which will be come part of the
* dataset id.
*
* To ensure that not two users generates the same dataset identifier
* the current time in base 36 is appended to the identifier.
*
* Base 36 was choosen to make the number as short as possible while
* at the same time not being case sensitive.
*/
public class MetnoDatasetIdentifierWidget extends EditorWidget {
private static final long serialVersionUID = -3840255996843857527L;
private String generatorId = "a";
public MetnoDatasetIdentifierWidget(){
super();
Config config = new Config("/metadataeditor.properties", Config.ENV_NAME);
generatorId = config.getRequired("widget.metnodatasetidentifier.generatorid");
}
/**
* Constructor that takes the generator id as a parameter instead of reading it
* from config. Only meant to be used from unit tests.
* @param generatorId The generator id to use for the widget.
*/
MetnoDatasetIdentifierWidget(String generatorId){
super();
this.generatorId = generatorId;
}
@Override
public Map<String, String> getDefaultValue() {
Map<String,String> defaultValue = new HashMap<>();
defaultValue.put("str", "");
return defaultValue;
}
@Override
protected void validateConfiguration(){
if( getMaxOccurs() != 1 ){
throw new InvalidEditorConfigurationException("maxOccurs for a variable associated with a MetnoDatasetIdentifierWidget must be 1", InvalidEditorConfigurationException.INVALID_WIDGET_CONFIG);
}
if( getMinOccurs() != 1 ){
throw new InvalidEditorConfigurationException("minOccurs for a variable associated with a MetnoDatasetIdentifierWidget must be 1", InvalidEditorConfigurationException.INVALID_WIDGET_CONFIG);
}
if( !getAttributeClass().equals(StringAttribute.class)){
throw new InvalidEditorConfigurationException("A MetnoDatasetIdentifierWidget must be associated with a string attribute", InvalidEditorConfigurationException.INVALID_WIDGET_CONFIG);
}
}
@Override
protected EditorVariableContent getContentForView(EditorWidgetView view){
Map<String,String> values = view.getValues();
String value = values.get("str");
if( "".equals(value)){
return super.getContentForView(view);
}
if( isNewValue(value) ){
value = value + "-" + generatorId + "-" + base36Timestamp();
}
EditorVariableContent content = new EditorVariableContent();
StringAttribute sa = new StringAttribute();
sa.addAttribute("str", value);
content.setAttrs(sa);
return content;
}
private boolean isNewValue(String value){
if( Pattern.matches(".*-" + generatorId + "-[\\w\\d]+", value)){
return false;
}
return true;
}
private String base36Timestamp(){
int currentSeconds = (int) (System.currentTimeMillis() / 1000);
return Integer.toString(currentSeconds, 36);
}
}