package uk.ac.ebi.fg.myequivalents.provenance.model;
import static org.apache.commons.lang3.StringUtils.trimToNull;
import static uk.ac.ebi.fg.myequivalents.resources.Const.COL_LENGTH_S;
import static uk.ac.ebi.fg.myequivalents.resources.Const.COL_LENGTH_URIS;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.Index;
import uk.ac.ebi.fg.myequivalents.model.Describeable;
import uk.ac.ebi.fg.myequivalents.model.Entity;
import uk.ac.ebi.fg.myequivalents.model.EntityId;
import uk.ac.ebi.fg.myequivalents.model.MyEquivalentsModelMember;
import uk.ac.ebi.fg.myequivalents.model.Service;
import uk.ac.ebi.fg.myequivalents.utils.EntityIdResolver;
/**
* The parameters passed to a given operation. These might be entity IDs, service names etc.
*
* <dl><dt>date</dt><dd>6 Jun 2014</dd></dl>
* @author Marco Brandizi
*
*/
@Embeddable
@XmlRootElement ( name = "prov-operation-parameter" )
@XmlAccessorType ( XmlAccessType.NONE )
public class ProvenanceRegisterParameter
{
private String valueType;
private String value;
private String extraValue;
protected ProvenanceRegisterParameter () {
}
public ProvenanceRegisterParameter ( String valueType, String value, String extraValue )
{
super ();
this.valueType = valueType;
this.value = value;
this.extraValue = extraValue;
}
public ProvenanceRegisterParameter ( String valueType, String value )
{
this ( valueType, value, null );
}
/**
* Might be strings like 'service', 'entity' etc.
*/
@Column ( length = COL_LENGTH_S )
@Index ( name = "prov_param_vtype" )
@XmlAttribute ( name = "value-type" )
public String getValueType ()
{
return valueType;
}
protected void setValueType ( String valueType )
{
this.valueType = valueType;
}
/**
* Might be things like 'service1', 'repository10', etc
*/
@Column ( length = COL_LENGTH_URIS )
@Index ( name = "prov_param_val" )
@XmlAttribute ( name = "value" )
public String getValue ()
{
return value;
}
protected void setValue ( String value )
{
this.value = value;
}
/**
* Might be things like 'acc1', for parameters like entityId = 'service1:acc1'
*/
@Column ( length = COL_LENGTH_URIS )
@Index ( name = "prov_param_extra1" )
@XmlAttribute ( name = "extra-value" )
public String getExtraValue ()
{
return extraValue;
}
protected void setExtraValue ( String extraValue )
{
this.extraValue = extraValue;
}
@Override
public boolean equals ( Object o )
{
if ( o == null ) return false;
if ( this == o ) return true;
if ( this.getClass () != o.getClass () ) return false;
// The entity type
ProvenanceRegisterParameter that = (ProvenanceRegisterParameter) o;
if ( this.getValueType () == null ? that.getValueType () != null : !this.valueType.equals ( that.valueType ) ) return false;
if ( this.getValue () == null ? that.getValue () != null : !this.value.equals ( that.value ) ) return false;
if ( this.getExtraValue () == null ? that.getExtraValue () != null : !this.extraValue.equals ( that.extraValue ) ) return false;
return true;
}
@Override
public int hashCode ()
{
int result = 1;
result = 31 * result + ( ( this.getValueType () == null ) ? 0 : valueType.hashCode () );
result = 31 * result + ( ( this.getValue () == null ) ? 0 : value.hashCode () );
result = 31 * result + ( ( this.getExtraValue () == null ) ? 0 : extraValue.hashCode () );
return result;
}
@Override
public String toString()
{
return String.format (
"%s { valueType: '%s', value: '%s', extraValue: '%s' }",
this.getClass ().getSimpleName (), getValueType (), getValue (), getExtraValue ()
);
}
/**
* Builds a parameter out of its string components
*/
public static ProvenanceRegisterParameter p ( String valueType, String value, String extraValue ) {
return new ProvenanceRegisterParameter ( valueType, value, extraValue );
}
/**
* Builds a parameter from its string components (null extraValue)
*/
public static ProvenanceRegisterParameter p ( String valueType, String value ) {
return new ProvenanceRegisterParameter ( valueType, value, null );
}
/**
* Builds a parameter using a string in the form {@code "type:value[:extraValue]"}
*/
public static ProvenanceRegisterParameter p ( String paramStr )
{
String[] ochunks = paramStr.split ( ":", -2 );
String ptype = ochunks.length > 0 ? trimToNull ( ochunks [ 0 ] ) : null;
String pval = ochunks.length > 1 ? trimToNull ( ochunks [ 1 ] ) : null;
String pxval = ochunks.length > 2 ? trimToNull ( ochunks [ 2 ] ) : null;
return p ( ptype, pval, pxval );
}
/**
* Builds a parameter using a string in the form {@code "type:value[:extraValue]"}
*/
public static List<ProvenanceRegisterParameter> p ( List<ProvenanceRegisterParameter> result, List<String> paramsStr )
{
if ( paramsStr == null || paramsStr.isEmpty () ) return result;
if ( result == null ) result = new ArrayList<ProvenanceRegisterParameter> ( paramsStr.size () );
for ( String pstr: paramsStr )
result.add ( p ( pstr ) );
return result;
}
public static List<ProvenanceRegisterParameter> p ( List<String> paramsStr ) {
return p ( (List<ProvenanceRegisterParameter>) null, paramsStr );
}
/**
* Builds p ( "entity", "service1", "acc1" )
*/
public static ProvenanceRegisterParameter pent ( String serviceName, String acc ) {
return new ProvenanceRegisterParameter ( "entity", serviceName, acc );
}
/**
* Builds p ( "entity", entityId ). The entity resolver is necessary because we always save IDs in the form
* service:acc in the provenance records.
*/
public static ProvenanceRegisterParameter pent ( EntityIdResolver entityIdResolver, String entityId )
{
EntityId eid = entityIdResolver.doall ( entityId );
return pent ( eid.getServiceName (), eid.getAcc () );
}
/**
* Builds p ( "service", service.getName () ).
*/
public static ProvenanceRegisterParameter p ( Service service ) {
return new ProvenanceRegisterParameter ( "service", service.getName () );
}
/**
* Builds p ( uncapitalize ( d.class.simpleName ), service.name ).
*/
public static ProvenanceRegisterParameter p ( Describeable d )
{
return new ProvenanceRegisterParameter (
StringUtils.uncapitalize ( d.getClass ().getSimpleName () ),
d.getName ()
);
}
/**
* Builds p ( "entity", e.serviceName, e.accession ).
*/
public static ProvenanceRegisterParameter p ( Entity e ) {
return new ProvenanceRegisterParameter ( "entity", e.getServiceName (), e.getAccession () );
}
/**
* Calls previous methods based on the class object is instance of.
*/
public static <MM extends MyEquivalentsModelMember> ProvenanceRegisterParameter p ( MM object )
{
if ( object instanceof Service ) return p ( (Service) object );
else if ( object instanceof Describeable ) return p ( (Describeable) object );
else if ( object instanceof Entity ) return p ( (Entity) object );
throw new RuntimeException (
"Cannot track provenance for unknown type " + object.getClass ().getName ()
);
}
/**
* Uses {@link #p(MyEquivalentsModelMember)} for each object in the collection, adds the parameters built to result.
* result may be null, in which case it will be initialised with an empty list.
*/
public static <MM extends MyEquivalentsModelMember> List<ProvenanceRegisterParameter> p
( List<ProvenanceRegisterParameter> result, Collection<MM> objects )
{
if ( objects == null || objects.isEmpty () ) return result;
if ( result == null ) result = new ArrayList<ProvenanceRegisterParameter> ( objects.size () );
for ( MM object: objects ) result.add ( p ( object ) );
return result;
}
/**
* Wraps {@link #p(List, Collection)} with null result.
*/
public static <MM extends MyEquivalentsModelMember> List<ProvenanceRegisterParameter> p ( Collection<MM> objects )
{
return p ( null, objects );
}
/**
* Generate parameters having all the same valueType. Adds them to result, initialises result with an empty list, if
* it's null.
*/
public static List<ProvenanceRegisterParameter> p ( List<ProvenanceRegisterParameter> result, String valueType, List<String> values )
{
if ( values == null || values.isEmpty () ) return result;
if ( result == null ) result = new ArrayList<ProvenanceRegisterParameter> ( values.size () );
for ( String value: values ) result.add ( p ( valueType, value ) );
return result;
}
/**
* Wraps {@link #p(List, String, List)} with result = null.
*/
public static List<ProvenanceRegisterParameter> p ( String valueType, List<String> values ) {
return p ( null, valueType, values );
}
/**
* Builds parameters for entity IDs. Adds up to result, which is initialised with an empty list, if it's null.
* @see #pent(EntityIdResolver, String) about the entityResolver parameter.
*/
public static List<ProvenanceRegisterParameter> pent (
EntityIdResolver entityIdResolver, List<ProvenanceRegisterParameter> result, List<String> entityIds
)
{
if ( entityIds == null || entityIds.isEmpty () ) return result;
if ( result == null ) result = new ArrayList<ProvenanceRegisterParameter> ( entityIds.size () );
for ( String entityId: entityIds ) result.add ( pent ( entityIdResolver, entityId ) );
return result;
}
/**
* Wraps {@link #pent(List, List)} with result = null.
* @see #pent(EntityIdResolver, String) about the entityResolver parameter.
*
*/
public static List<ProvenanceRegisterParameter> pent ( EntityIdResolver entityIdResolver, List<String> entityIds )
{
return pent ( entityIdResolver, null, entityIds );
}
}