/*
* Licensed under the Apache License, Version 2.0 (the "License");
*
* You may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributions from 2013-2017 where performed either by US government
* employees, or under US Veterans Health Administration contracts.
*
* US Veterans Health Administration contributions by government employees
* are work of the U.S. Government and are not subject to copyright
* protection in the United States. Portions contributed by government
* employees are USGovWork (17USC ยง105). Not subject to copyright.
*
* Contribution by contractors to the US Veterans Health Administration
* during this period are contractually contributed under the
* Apache License, Version 2.0.
*
* See: https://www.usa.gov/government-works
*
* Contributions prior to 2013:
*
* Copyright (C) International Health Terminology Standards Development Organisation.
* Licensed under the Apache License, Version 2.0.
*
*/
package sh.isaac.api.component.sememe.version.dynamicSememe;
//~--- JDK imports ------------------------------------------------------------
import java.util.Arrays;
import java.util.UUID;
//~--- non-JDK imports --------------------------------------------------------
import sh.isaac.api.LookupService;
import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeFloat;
import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeString;
//~--- classes ----------------------------------------------------------------
/**
* {@link DynamicSememeColumnInfo}
*
* A user friendly class for containing the information parsed out of the Assemblage concepts which defines the DynamicSememe.
* See the class description for {@link DynamicSememeUsageDescriptionBI} for more details.
*
* @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a>
*/
public class DynamicSememeColumnInfo
implements Comparable<DynamicSememeColumnInfo> {
/** The column description concept UUI D. */
private UUID columnDescriptionConceptUUID;
/** The column name. */
private transient String columnName;
/** The column description. */
private transient String columnDescription;
/** The index column. */
private transient Boolean indexColumn; // This is not populated by default, nor is it stored. Typically used to pass data from a constant, rather
/** The column order. */
// than run-time lookup of the index configuration.
private int columnOrder;
/** The assemblage concept. */
private UUID assemblageConcept;
/** The column data type. */
private DynamicSememeDataType columnDataType;
/** The default data. */
private DynamicSememeData defaultData;
/** The column required. */
private boolean columnRequired;
/** The validator type. */
private DynamicSememeValidatorType[] validatorType;
/** The validator data. */
private DynamicSememeData[] validatorData;
//~--- constructors --------------------------------------------------------
/**
* Useful for building up a new one step by step.
*/
public DynamicSememeColumnInfo() {}
/**
* calls {@link #DynamicSememeColumnInfo(UUID, int, UUID, DynamicSememeDataType, DynamicSememeDataBI, Boolean, DynamicSememeValidatorType[], DynamicSememeDataBI[])
* with a null assemblage concept, null validator info.
*
* @param columnOrder the column order
* @param columnDescriptionConcept the column description concept
* @param columnDataType the column data type
* @param defaultData the default data
* @param columnRequired the column required
* @param index the index
*/
public DynamicSememeColumnInfo(int columnOrder,
UUID columnDescriptionConcept,
DynamicSememeDataType columnDataType,
DynamicSememeData defaultData,
Boolean columnRequired,
Boolean index) {
this(null, columnOrder, columnDescriptionConcept, columnDataType, defaultData, columnRequired, null, null, index);
}
/**
* calls {@link #DynamicSememeColumnInfo(UUID, int, UUID, DynamicSememeDataType, DynamicSememeDataBI, Boolean, DynamicSememeValidatorType[], DynamicSememeDataBI[])
* with a null assemblage concept, and a single array item for the validator info.
*
* @param columnOrder the column order
* @param columnDescriptionConcept the column description concept
* @param columnDataType the column data type
* @param defaultData the default data
* @param columnRequired the column required
* @param validatorType the validator type
* @param validatorData the validator data
* @param index the index
*/
public DynamicSememeColumnInfo(int columnOrder,
UUID columnDescriptionConcept,
DynamicSememeDataType columnDataType,
DynamicSememeData defaultData,
Boolean columnRequired,
DynamicSememeValidatorType validatorType,
DynamicSememeData validatorData,
Boolean index) {
this(null,
columnOrder,
columnDescriptionConcept,
columnDataType,
defaultData,
columnRequired,
(validatorType == null) ? null
: new DynamicSememeValidatorType[] { validatorType },
(validatorData == null) ? null
: new DynamicSememeData[] { validatorData },
index);
}
/**
* calls {@link #DynamicSememeColumnInfo(UUID, int, UUID, DynamicSememeDataType, DynamicSememeDataBI, Boolean, DynamicSememeValidatorType, DynamicSememeDataBI)
* with a null assemblage concept.
*
* @param columnOrder the column order
* @param columnDescriptionConcept the column description concept
* @param columnDataType the column data type
* @param defaultData the default data
* @param columnRequired the column required
* @param validatorType the validator type
* @param validatorData the validator data
* @param index the index
*/
public DynamicSememeColumnInfo(int columnOrder,
UUID columnDescriptionConcept,
DynamicSememeDataType columnDataType,
DynamicSememeData defaultData,
Boolean columnRequired,
DynamicSememeValidatorType[] validatorType,
DynamicSememeData[] validatorData,
Boolean index) {
this(null,
columnOrder,
columnDescriptionConcept,
columnDataType,
defaultData,
columnRequired,
validatorType,
validatorData,
index);
}
/**
* Create this object by reading the columnName and columnDescription from the provided columnDescriptionConcept.
*
* If a suitable concept to use for the column Name/Description does not yet exist, see
* {@link DynamicSememeColumnInfo#createNewDynamicSememeColumnInfoConcept(String, String)}
*
* and pass the result in here.
*
* @param assemblageConcept - the assemblage concept that this was read from (or null, if not yet part of an assemblage)
* @param columnOrder - the column order as defined in the assemblage concept
* @param columnDescriptionConcept - The concept where columnName and columnDescription should be read from
* @param columnDataType - the data type as defined in the assemblage concept
* @param defaultData - The type of this Object must align with the data type specified in columnDataType. For example,
* if columnDataType is set to {@link DynamicSememeDataType#FLOAT} then this field must be a {@link DynamicSememeFloat}.
* @param columnRequired - Is this column required when creating an instance of the refex? True for yes, false or null for no.
* @param validatorType - The Validator to use when creating an instance of this Refex. Null for no validator
* @param validatorData - The data required to execute the validatorType specified. The format and type of this will depend on the
* validatorType field. See {@link DynamicSememeValidatorType} for details on the valid data for this field. Should be null when validatorType is null.
* @param index - set to true, if this column should be indexed.
*/
public DynamicSememeColumnInfo(UUID assemblageConcept,
int columnOrder,
UUID columnDescriptionConcept,
DynamicSememeDataType columnDataType,
DynamicSememeData defaultData,
Boolean columnRequired,
DynamicSememeValidatorType[] validatorType,
DynamicSememeData[] validatorData,
Boolean index) {
this.assemblageConcept = assemblageConcept;
this.columnOrder = columnOrder;
this.columnDescriptionConceptUUID = columnDescriptionConcept;
this.columnDataType = columnDataType;
this.defaultData = defaultData;
this.columnRequired = ((columnRequired == null) ? false
: columnRequired);
this.validatorType = validatorType;
this.validatorData = validatorData;
this.indexColumn = index;
}
//~--- methods -------------------------------------------------------------
/**
* Compare to.
*
* @param o the o
* @return the int
*/
/*
* @see java.lang.Comparable#compareTo(java.lang.Object)
*/
@Override
public int compareTo(DynamicSememeColumnInfo o) {
return Integer.compare(this.getColumnOrder(), o.getColumnOrder());
}
/**
* To string.
*
* @return the string
*/
@Override
public String toString() {
return "DynamicSememeColumnInfo [columnName_=" + this.columnName + ", columnDescription_=" +
this.columnDescription + ", columnOrder_=" + this.columnOrder + ", assemblageConcept_=" +
this.assemblageConcept + ", columnDataType_=" + this.columnDataType + ", defaultData_=" +
this.defaultData + ", columnRequired_=" + this.columnRequired + ", validatorType_=" +
Arrays.toString(this.validatorType) + ", validatorData_=" + Arrays.toString(this.validatorData) + "]";
}
/**
* Read.
*/
private void read() {
final DynamicSememeColumnUtility util = LookupService.get()
.getService(DynamicSememeColumnUtility.class);
if (util == null) {
this.columnName = "Unable to locate reader!";
this.columnDescription = "Unable to locate reader!";
} else {
final String[] temp = util.readDynamicSememeColumnNameDescription(this.columnDescriptionConceptUUID);
this.columnName = temp[0];
this.columnDescription = temp[1];
}
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the assemblage concept.
*
* @return the UUID of the assemblage concept that this column data was read from
* or null in the case where this column is not yet associated with an assemblage.
*/
public UUID getAssemblageConcept() {
return this.assemblageConcept;
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the assemblage concept.
*
* @param assemblageConcept - the assemblage concept that this was read from (or null, if not yet part of an assemblage)
*/
public void setAssemblageConcept(UUID assemblageConcept) {
this.assemblageConcept = assemblageConcept;
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the column data type.
*
* @return The defined data type for this column of the sememe. Note that this value will be identical to the {@link DynamicSememeDataType}
* returned by {@link DynamicSememeData} EXCEPT for cases where this returns {@link DynamicSememeDataType#POLYMORPHIC}. In those cases, the
* data type can only be determined by examining the actual member data in {@link DynamicSememeData}
*/
public DynamicSememeDataType getColumnDataType() {
return this.columnDataType;
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the column data type.
*
* @param columnDataType - the data type as defined in the assemblage concept
*/
public void setColumnDataType(DynamicSememeDataType columnDataType) {
this.columnDataType = columnDataType;
}
/**
* Sets the column default data.
*
* @param defaultData - The type of this Object must align with the data type specified in columnDataType. For example,
* if columnDataType is set to {@link DynamicSememeDataType#FLOAT} then this field must be a {@link DynamicSememeFloat}.
*/
public void setColumnDefaultData(DynamicSememeData defaultData) {
this.defaultData = defaultData;
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the column description.
*
* @return The user-friendly description of this column of data. To be used by GUIs to provide a more detailed explanation of
* the type of data found in this column.
*/
public String getColumnDescription() {
if (this.columnDescription == null) {
read();
}
return this.columnDescription;
}
/**
* Gets the column description concept.
*
* @return The UUID of the concept where the columnName and columnDescription were read from.
*/
public UUID getColumnDescriptionConcept() {
return this.columnDescriptionConceptUUID;
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the column description concept.
*
* @param columnDescriptionConcept - The concept where columnName and columnDescription should be read from
*/
public void setColumnDescriptionConcept(UUID columnDescriptionConcept) {
this.columnDescriptionConceptUUID = columnDescriptionConcept;
this.columnName = null;
this.columnDescription = null;
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the column name.
*
* @return The user-friendly name of this column of data. To be used by GUIs to label the data in this column.
*/
public String getColumnName() {
if (this.columnName == null) {
read();
}
return this.columnName;
}
/**
* Gets the column order.
*
* @return Defined the order in which the data columns will be stored, so that the column name / description can be aligned
* with the {@link DynamicSememeData} columns in the {@link DynamicSememeVersionBI#getData(int)}.
*
* Note, this value is 0 indexed (It doesn't start at 1)
*/
public int getColumnOrder() {
return this.columnOrder;
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the column order.
*
* @param columnOrder - the column order as defined in the assemblage concept
*/
public void setColumnOrder(int columnOrder) {
this.columnOrder = columnOrder;
}
//~--- get methods ---------------------------------------------------------
/**
* Checks if column required.
*
* @return When creating this refex, must this column be provided?
*/
public boolean isColumnRequired() {
return this.columnRequired;
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the column required.
*
* @param columnRequired - Is this column required when creating an instance of the sememe? True for yes, false or null for no.
*/
public void setColumnRequired(boolean columnRequired) {
this.columnRequired = columnRequired;
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the default column value.
*
* @return the default value to use for this column, if no value is specified in a refex that is created using this column info
*/
public DynamicSememeData getDefaultColumnValue() {
// Handle folks sending empty strings gracefully
if ((this.defaultData != null) &&
(this.defaultData instanceof DynamicSememeString) &&
((DynamicSememeString) this.defaultData).getDataString().length() == 0) {
return null;
}
return this.defaultData;
}
//~--- set methods ---------------------------------------------------------
/**
* This is typically used in the metadata code to pass in the initial index configuration for a column. It has no impact on
* the actual config at runtime, in a running system.
*
* @param indexColumn the new default index config
*/
public void setDefaultIndexConfig(boolean indexColumn) {
this.indexColumn = indexColumn;
}
//~--- get methods ---------------------------------------------------------
/**
* Return true, if this column is currently configured for indexing, otherwise false. Note, this is not currently implemented runtime usage
* and will instead throw an UnsupportedOperationException. This is only used in the construction of metadata concepts.
*
* @return the index config
*/
public boolean getIndexConfig() {
if (this.indexColumn == null) {
throw new UnsupportedOperationException(
"Convenience method to read current index config from lucene indexer not yet implemented");
} else {
return this.indexColumn;
}
}
/**
* Gets the validator.
*
* @return The type of the validator(s) (if any) which must be used to validate user data before accepting the refex
*/
public DynamicSememeValidatorType[] getValidator() {
return this.validatorType;
}
/**
* Gets the validator data.
*
* @return the validator data
*/
public DynamicSememeData[] getValidatorData() {
return this.validatorData;
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the validator data.
*
* @param validatorData the new validator data
*/
public void setValidatorData(DynamicSememeData[] validatorData) {
this.validatorData = validatorData;
}
/**
* Sets the validator type.
*
* @param validatorType - The Validator(s) to use when creating an instance of this sememe. Null for no validator
*/
public void setValidatorType(DynamicSememeValidatorType[] validatorType) {
this.validatorType = validatorType;
}
}