com.hfg.automation.SimpleWell Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.automation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import com.hfg.bio.HfgBioXML;
import com.hfg.exception.InvalidValueException;
import com.hfg.units.Quantity;
import com.hfg.units.QuantityType;
import com.hfg.util.StringUtil;
import com.hfg.util.collection.CollectionUtil;
import com.hfg.util.collection.OrderedSet;
import com.hfg.xml.HfgXMLSerializable;
import com.hfg.xml.XMLNode;
import com.hfg.xml.XMLTag;
//------------------------------------------------------------------------------
/**
Generic well in a plate.
@author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class SimpleWell implements Well, Cloneable
{
private WellRef mLocation;
private WellType mType;
private Set mSamples;
private Float mRawResult;
private Quantity mVolume;
private SimplePlate mPlate;
private EnumSet mFlags;
public enum Flag
{
SELECTED,
ERROR
}
//###########################################################################
// CONSTRUCTORS
//###########################################################################
//---------------------------------------------------------------------------
public SimpleWell(WellRef inLocation)
{
mLocation = inLocation;
}
//---------------------------------------------------------------------------
public SimpleWell(WellRef inLocation, WellType inType)
{
mLocation = inLocation;
mType = inType;
}
//--------------------------------------------------------------------------
public SimpleWell(XMLNode inXML)
{
inXML.verifyTagName(AutomationXML.WELL);
mLocation = new WellRef(inXML.getAttributeValue(AutomationXML.REF_ATT));
if (inXML.hasAttribute(AutomationXML.TYPE_ATT))
{
setType(WellType.valueOf(inXML.getAttributeValue(AutomationXML.TYPE_ATT)));
}
if (inXML.hasAttribute(AutomationXML.VOL_ATT))
{
setVolume(new Quantity(inXML.getAttributeValue(AutomationXML.VOL_ATT)));
}
if (inXML.hasAttribute(AutomationXML.RAW_RESULT_ATT))
{
setRawResult(Float.parseFloat(inXML.getAttributeValue(AutomationXML.RAW_RESULT_ATT)));
}
if (inXML.hasAttribute(AutomationXML.FLAGS_ATT))
{
String[] stringValues = inXML.getAttributeValue(AutomationXML.FLAGS_ATT).split("[\\s,]+");
for (String stringValue : stringValues)
{
Flag flag = Flag.valueOf(stringValue);
if (null == mFlags)
{
mFlags = EnumSet.of(flag);
}
else
{
mFlags.add(flag);
}
}
}
List sampleTags = inXML.getOptionalSubtagByName(AutomationXML.SAMPLE);
if (CollectionUtil.hasValues(sampleTags))
{
for (XMLNode sampleTag : sampleTags)
{
String sampleClassname = sampleTag.getAttributeValue(HfgBioXML.CLASS_ATT);
if (! StringUtil.isSet(sampleClassname))
{
throw new RuntimeException("No " + AutomationXML.CLASS_ATT + " specified on the Sample's XML tag!");
}
S sample;
if (sampleClassname.equals(String.class.getName()))
{
sample = (S) sampleTag.getUnescapedContent();
}
else
{
try
{
Class clazz = Class.forName(sampleClassname);
Constructor constructor = clazz.getConstructor(XMLNode.class);
sample = (S) constructor.newInstance(sampleTag.getSubtags().get(0));
}
catch (Exception e)
{
throw new RuntimeException("Error during Sample instantiation from its XML tag!", e);
}
}
addSample(sample);
}
}
}
//###########################################################################
// PUBLIC METHODS
//###########################################################################
//--------------------------------------------------------------------------
public XMLNode toXMLNode()
{
XMLNode node = new XMLTag(AutomationXML.WELL);
node.setAttribute(AutomationXML.REF_ATT, getRef());
if (getType() != null)
{
node.setAttribute(AutomationXML.TYPE_ATT, getType());
}
if (getVolume() != null)
{
node.setAttribute(AutomationXML.VOL_ATT, getVolume());
}
if (getRawResult() != null)
{
node.setAttribute(AutomationXML.RAW_RESULT_ATT, getRawResult());
}
if (mFlags != null)
{
node.setAttribute(AutomationXML.FLAGS_ATT, StringUtil.join(mFlags, ", "));
}
if (CollectionUtil.hasValues(mSamples))
{
for (S sample : mSamples)
{
XMLNode sampleTag = new XMLTag(AutomationXML.SAMPLE);
sampleTag.setAttribute(AutomationXML.CLASS_ATT, sample.getClass().getName());
if (sample instanceof String)
{
sampleTag.setContent(sample.toString());
}
else
{
sampleTag.addSubtag(((HfgXMLSerializable) sample).toXMLNode());
}
sampleTag.addSubtag(sampleTag);
node.addSubtag(sampleTag);
}
}
return node;
}
//--------------------------------------------------------------------------
@Override
public SimpleWell clone()
{
SimpleWell theClone;
try
{
theClone = (SimpleWell) super.clone();
}
catch (CloneNotSupportedException e)
{
throw new RuntimeException(e);
}
if (mSamples != null)
{
theClone.mSamples = new OrderedSet<>(mSamples);
}
return theClone;
}
//---------------------------------------------------------------------------
public WellRef getRef()
{
return mLocation;
}
//---------------------------------------------------------------------------
public SimpleWell setType(WellType inValue)
{
mType = inValue;
return this;
}
//---------------------------------------------------------------------------
public WellType getType()
{
return mType;
}
//---------------------------------------------------------------------------
public SimpleWell setPlate(SimplePlate inValue)
{
mPlate = inValue;
return this;
}
//---------------------------------------------------------------------------
public SimplePlate getPlate()
{
return mPlate;
}
//---------------------------------------------------------------------------
public SimpleWell addSample(T inValue)
{
return addSample(inValue, (Class) inValue.getClass());
}
//---------------------------------------------------------------------------
public SimpleWell addSample(T inValue, Class inSampleClass)
{
if (null == mSamples)
{
mSamples = new OrderedSet<>(3);
}
mSamples.add((S)inValue);
return this;
}
//---------------------------------------------------------------------------
public S[] getSamples(Class inClass)
{
return mSamples != null && mSamples.iterator().next().getClass().equals(inClass)? mSamples.toArray((S[]) Array.newInstance(mSamples.iterator().next().getClass(), 0)) : null;
}
//---------------------------------------------------------------------------
@Override
public Comparable[] getSamples()
{
return mSamples != null ? mSamples.toArray((S[]) Array.newInstance(mSamples.iterator().next().getClass(), 0)) : null;
}
//---------------------------------------------------------------------------
public SimpleWell setVolume(Quantity inValue)
{
if (! inValue.getUnit().getQuantityType().equals(QuantityType.VOLUME))
{
throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inValue) + " isn't specified in volume units!");
}
mVolume = inValue;
return this;
}
//---------------------------------------------------------------------------
public SimpleWell addVolume(Quantity inValue)
{
if (inValue != null)
{
if (!inValue.getUnit().getQuantityType().equals(QuantityType.VOLUME))
{
throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inValue) + " isn't specified in volume units!");
}
if (mVolume != null)
{
mVolume = mVolume.add(inValue);
}
else
{
mVolume = inValue;
}
}
return this;
}
//---------------------------------------------------------------------------
public SimpleWell subtractVolume(Quantity inValue)
{
if (inValue != null)
{
if (!inValue.getUnit().getQuantityType().equals(QuantityType.VOLUME))
{
throw new InvalidValueException("The specified volume quantity " + StringUtil.singleQuote(inValue) + " isn't specified in volume units!");
}
if (null == mVolume)
{
throw new InvalidValueException("No initial volume in well " + getRef() + "! Can't subtract!");
}
else
{
mVolume = mVolume.subtract(inValue);
// TODO: Add check that the volume doesn't go below 0
}
}
return this;
}
//---------------------------------------------------------------------------
public Quantity getVolume()
{
return mVolume;
}
//---------------------------------------------------------------------------
/**
Specifies the raw result value read for this well.
@param inValue raw result as a float
@return this Well to enable method chaining
*/
public SimpleWell setRawResult(Float inValue)
{
mRawResult = inValue;
return this;
}
//---------------------------------------------------------------------------
/**
Returns the raw result value read for this well.
@return raw result as a float
*/
public Float getRawResult()
{
return mRawResult;
}
//---------------------------------------------------------------------------
public SimpleWell setSelected()
{
return setSelected(true);
}
//---------------------------------------------------------------------------
public SimpleWell setSelected(boolean inValue)
{
if (null == mFlags)
{
if (inValue)
{
mFlags = EnumSet.of(Flag.SELECTED);
}
}
else if (inValue)
{
mFlags.add(Flag.SELECTED);
}
else
{
mFlags.remove(Flag.SELECTED);
}
return this;
}
//---------------------------------------------------------------------------
public boolean isSelected()
{
return (mFlags != null && mFlags.contains(Flag.SELECTED));
}
}