Java tutorial
/* * Wildbook - A Mark-Recapture Framework * Copyright (C) 2011-2013 Jason Holmberg * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.ecocean; import java.io.IOException; import java.util.*; import org.ecocean.genetics.*; import org.ecocean.social.Relationship; import org.ecocean.security.Collaboration; import org.ecocean.media.MediaAsset; import org.ecocean.servlet.ServletUtilities; import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.builder.ToStringBuilder; import java.text.DecimalFormat; import org.datanucleus.api.rest.orgjson.JSONObject; import org.datanucleus.api.rest.orgjson.JSONArray; import org.datanucleus.api.rest.orgjson.JSONException; /** * A <code>MarkedIndividual</code> object stores the complete <code>encounter</code> data for a single marked individual in a mark-recapture study. * <code>Encounters</code> are added to MarkedIndividual objects as multiple encounters are associated with * known marked individuals. * <p/> * * @author Jason Holmberg * @version 2.0 * @see Encounter, Shepherd */ public class MarkedIndividual implements java.io.Serializable { //unique name of the MarkedIndividual, such as 'A-109' private String individualID = ""; //alternate id for the MarkedIndividual, such as a physical tag number of reference in another database private String alternateid; //additional comments added by researchers private String comments = "None"; //sex of the MarkedIndividual private String sex = "unknown"; private String genus = ""; private String specificEpithet; //unused String that allows groups of MarkedIndividuals by optional parameters private String seriesCode = "None"; //nickname for the MarkedIndividual...not used for any scientific purpose //also the nicknamer for credit private String nickName = "", nickNamer = ""; //Vector of approved encounter objects added to this MarkedIndividual private Vector<Encounter> encounters = new Vector<Encounter>(); //Vector of unapproved encounter objects added to this MarkedIndividual //private Vector unidentifiableEncounters = new Vector(); //Vector of String filenames of additional files added to the MarkedIndividual private Vector dataFiles = new Vector(); //number of encounters of this MarkedIndividual private int numberEncounters; //number of unapproved encounters (log) of this MarkedIndividual //private int numUnidentifiableEncounters; //number of locations for this MarkedIndividual private int numberLocations; //first sighting private String dateFirstIdentified; //points to thumbnail (usually of most recent encounter) - TODO someday will be superceded by MediaAsset magic[tm] private String thumbnailUrl; //a Vector of Strings of email addresses to notify when this MarkedIndividual is modified private Vector interestedResearchers = new Vector(); private String dateTimeCreated; private String dateTimeLatestSighting; //FOR FAST QUERY PURPOSES ONLY - DO NOT MANUALLY SET private String localHaplotypeReflection; private String dynamicProperties; private String patterningCode; private int maxYearsBetweenResightings; private long timeOfBirth = 0; private long timeOfDeath = 0; public MarkedIndividual(String individualID, Encounter enc) { this.individualID = individualID; encounters.add(enc); //dataFiles = new Vector(); numberEncounters = 1; if (enc.getSex() != null) { this.sex = enc.getSex(); } //numUnidentifiableEncounters = 0; setTaxonomyFromEncounters(); setSexFromEncounters(); maxYearsBetweenResightings = 0; } /** * empty constructor used by JDO Enhancer - DO NOT USE */ public MarkedIndividual() { } /**Adds a new encounter to this MarkedIndividual. *@param newEncounter the new <code>encounter</code> to add *@return true for successful addition, false for unsuccessful - Note: this change must still be committed for it to be stored in the database *@see Shepherd#commitDBTransaction() */ public boolean addEncounter(Encounter newEncounter, String context) { newEncounter.assignToMarkedIndividual(individualID); //get and therefore set the haplotype if necessary getHaplotype(); boolean isNew = true; for (int i = 0; i < encounters.size(); i++) { Encounter tempEnc = (Encounter) encounters.get(i); if (tempEnc.getEncounterNumber().equals(newEncounter.getEncounterNumber())) { isNew = false; } } //prevent duplicate addition of encounters if (isNew) { encounters.add(newEncounter); numberEncounters++; refreshDependentProperties(context); } setTaxonomyFromEncounters(); //will only set if has no value setSexFromEncounters(); //likewise return isNew; } /**Removes an encounter from this MarkedIndividual. *@param getRidOfMe the <code>encounter</code> to remove from this MarkedIndividual *@return true for successful removal, false for unsuccessful - Note: this change must still be committed for it to be stored in the database *@see Shepherd#commitDBTransaction() */ public boolean removeEncounter(Encounter getRidOfMe, String context) { numberEncounters--; boolean changed = false; for (int i = 0; i < encounters.size(); i++) { Encounter tempEnc = (Encounter) encounters.get(i); if (tempEnc.getEncounterNumber().equals(getRidOfMe.getEncounterNumber())) { encounters.remove(i); i--; changed = true; } } refreshDependentProperties(context); //reset haplotype localHaplotypeReflection = null; getHaplotype(); return changed; } /** * Returns the total number of submitted encounters for this MarkedIndividual * * @return the total number of encounters recorded for this MarkedIndividual */ public int totalEncounters() { return encounters.size(); } public int refreshNumberEncounters() { this.numberEncounters = encounters.size(); return this.numberEncounters; } public String getDateFirstIdentified() { return this.dateFirstIdentified; } public String refreshDateFirstIdentified() { Encounter[] sorted = this.getDateSortedEncounters(); if (sorted.length < 1) return null; Encounter first = sorted[sorted.length - 1]; if (first.getYear() < 1) return null; String d = new Integer(first.getYear()).toString(); if (first.getMonth() > 0) d = new Integer(first.getMonth()).toString() + "/" + d; this.dateFirstIdentified = d; return d; } public String refreshDateLastestSighting() { Encounter[] sorted = this.getDateSortedEncounters(true); if (sorted.length < 1) return null; Encounter last = sorted[0]; if (last.getYear() < 1) return null; this.dateTimeLatestSighting = last.getDate(); return last.getDate(); } public String refreshThumbnailUrl(String context) { Encounter[] sorted = this.getDateSortedEncounters(); if (sorted.length < 1) return null; this.thumbnailUrl = sorted[0].getThumbnailUrl(context); return this.thumbnailUrl; } /* public int totalLogEncounters() { if (unidentifiableEncounters == null) { //unidentifiableEncounters = new Vector(); } return unidentifiableEncounters.size(); } */ public Vector returnEncountersWithGPSData() { return returnEncountersWithGPSData(false, false, "context0"); } public Vector returnEncountersWithGPSData(boolean useLocales, boolean reverseOrder, String context) { //if(unidentifiableEncounters==null) {unidentifiableEncounters=new Vector();} Vector haveData = new Vector(); Encounter[] myEncs = getDateSortedEncounters(reverseOrder); Properties localesProps = new Properties(); if (useLocales) { try { localesProps = ShepherdProperties.getProperties("locationIDGPS.properties", "", context); } catch (Exception ioe) { ioe.printStackTrace(); } } for (int c = 0; c < myEncs.length; c++) { Encounter temp = myEncs[c]; if ((temp.getDWCDecimalLatitude() != null) && (temp.getDWCDecimalLongitude() != null)) { haveData.add(temp); } else if (useLocales && (temp.getLocationID() != null) && (localesProps.getProperty(temp.getLocationID()) != null)) { haveData.add(temp); } } return haveData; } public boolean isDeceased() { //if (unidentifiableEncounters == null) { // unidentifiableEncounters = new Vector(); //} for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.getLivingStatus().equals("dead")) { return true; } } /* for (int d = 0; d < numUnidentifiableEncounters; d++) { Encounter temp = (Encounter) unidentifiableEncounters.get(d); if (temp.getLivingStatus().equals("dead")) { return true; } } */ return false; } public boolean wasSightedInYear(int year) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.getYear() == year) { return true; } } return false; } public boolean wasSightedInYear(int year, String locCode) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() == year) && (temp.getLocationCode().startsWith(locCode))) { return true; } } return false; } public boolean wasSightedInYearLeftTagsOnly(int year, String locCode) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() == year) && (temp.getLocationCode().startsWith(locCode)) && (temp.getNumSpots() > 0)) { return true; } } return false; } /** * * * @deprecated */ public double averageLengthInYear(int year) { int numLengths = 0; double total = 0; double avg = 0; for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() == year) && ((temp.getSizeAsDouble() != null) && (temp.getSize() > 0))) { total += temp.getSize(); numLengths++; } } if (numLengths > 0) { avg = total / numLengths; } return avg; } /** * * * @deprecated */ public double averageMeasuredLengthInYear(int year, boolean allowGuideGuess) { int numLengths = 0; double total = 0; double avg = 0; for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.getYear() == year) { if ((temp.getSizeAsDouble() != null) && (temp.getSize() > 0)) { if ((temp.getSizeGuess().equals("directly measured")) || ((allowGuideGuess) && (temp.getSizeGuess().equals("guide/researcher's guess")))) { total += temp.getSize(); numLengths++; } } } } if (numLengths > 0) { avg = total / numLengths; } return avg; } //use the index identifier, not the full name of the keyword public boolean isDescribedByPhotoKeyword(Keyword word) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.hasKeyword(word)) { return true; } } return false; } /* public boolean hasApprovedEncounters() { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.getState()!=null) { return true; } } return false; } */ public boolean wasSightedInMonth(int year, int month) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() == year) && (temp.getMonth() == month)) { return true; } } return false; } public boolean wasSightedInPeriod(int m_startYear, int m_startMonth, int m_endYear, int m_endMonth) { int endYear = m_endYear; int endMonth = m_endMonth; int startYear = m_startYear; int startMonth = m_startMonth; GregorianCalendar gcMin = new GregorianCalendar(startYear, startMonth, 1); GregorianCalendar gcMax = new GregorianCalendar(endYear, endMonth, 31); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getDateInMilliseconds() != null) && (temp.getDateInMilliseconds() >= gcMin.getTimeInMillis()) && (temp.getDateInMilliseconds() <= gcMax.getTimeInMillis())) { return true; } } return false; } public boolean wasSightedInPeriod(int m_startYear, int m_startMonth, int m_startDay, int m_endYear, int m_endMonth, int m_endDay, String locCode) { int endYear = m_endYear; int endMonth = m_endMonth; int endDay = m_endDay; int startYear = m_startYear; int startMonth = m_startMonth; int startDay = m_startDay; GregorianCalendar gcMin = new GregorianCalendar(startYear, startMonth, startDay); GregorianCalendar gcMax = new GregorianCalendar(endYear, endMonth, endDay); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getLocationID() != null) && (!temp.getLocationID().trim().equals("")) && (temp.getLocationID().trim().equals(locCode))) { if ((temp.getDateInMilliseconds() != null) && (temp.getDateInMilliseconds() >= gcMin.getTimeInMillis()) && (temp.getDateInMilliseconds() <= gcMax.getTimeInMillis())) { return true; } } } return false; } public boolean wasSightedInPeriod(int m_startYear, int m_startMonth, int m_startDay, int m_endYear, int m_endMonth, int m_endDay) { int endYear = m_endYear; int endMonth = m_endMonth; int endDay = m_endDay; int startYear = m_startYear; int startMonth = m_startMonth; int startDay = m_startDay; GregorianCalendar gcMin = new GregorianCalendar(startYear, startMonth, startDay); GregorianCalendar gcMax = new GregorianCalendar(endYear, endMonth, endDay); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getDateInMilliseconds() != null) && (temp.getDateInMilliseconds() >= gcMin.getTimeInMillis()) && (temp.getDateInMilliseconds() <= gcMax.getTimeInMillis())) { return true; } } return false; } public boolean wasSightedInPeriodLeftOnly(int m_startYear, int m_startMonth, int m_endYear, int m_endMonth) { int endYear = m_endYear; int endMonth = m_endMonth; int startYear = m_startYear; int startMonth = m_startMonth; GregorianCalendar gcMin = new GregorianCalendar(startYear, startMonth, 1); GregorianCalendar gcMax = new GregorianCalendar(endYear, endMonth, 31); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getDateInMilliseconds() != null) && (temp.getDateInMilliseconds() >= gcMin.getTimeInMillis()) && (temp.getDateInMilliseconds() <= gcMax.getTimeInMillis()) && (temp.getNumSpots() > 0)) { return true; } } return false; } /** * Returns the user-input name of the MarkedIndividual, which is also used as an Index in the FastObjects database * * @return the name of the MarkedIndividual as a String */ public String getName() { return individualID; } public String getIndividualID() { return individualID; } public String getNickName() { if (nickName != null) { return nickName; } else { return "Unassigned"; } } public String getNickNamer() { if (nickNamer != null) { return nickNamer; } else { return "Unknown"; } } /** * Sets the nickname of the MarkedIndividual. */ public void setNickName(String newName) { nickName = newName; } public void setNickNamer(String newNamer) { nickNamer = newNamer; } public void setName(String newName) { individualID = newName; } public void setIndividualID(String newName) { individualID = newName; } /** * Returns the specified encounter, where the encounter numbers range from 0 to n-1, where n is the total number of encounters stored * for this MarkedIndividual. * * @return the encounter at position i in the stored Vector of encounters * @param i the specified encounter number, where i=0...(n-1) */ public Encounter getEncounter(int i) { return (Encounter) encounters.get(i); } /* public Encounter getLogEncounter(int i) { return (Encounter) unidentifiableEncounters.get(i); } */ /** * Returns the complete Vector of stored encounters for this MarkedIndividual. * * @return a Vector of encounters * @see java.util.Vector */ public Vector getEncounters() { return encounters; } //you can choose the order of the EncounterDateComparator public Encounter[] getDateSortedEncounters(boolean reverse) { Vector final_encs = new Vector(); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); final_encs.add(temp); } int finalNum = final_encs.size(); Encounter[] encs2 = new Encounter[finalNum]; for (int q = 0; q < finalNum; q++) { encs2[q] = (Encounter) final_encs.get(q); } EncounterDateComparator dc = new EncounterDateComparator(reverse); Arrays.sort(encs2, dc); return encs2; } //sorted with the most recent first public Encounter[] getDateSortedEncounters() { return getDateSortedEncounters(false); } //preserved for legacy purposes /** public Encounter[] getDateSortedEncounters(boolean includeLogEncounters) { return getDateSortedEncounters(); } */ /* public Vector getUnidentifiableEncounters() { if (unidentifiableEncounters == null) { unidentifiableEncounters = new Vector(); } return unidentifiableEncounters; } */ /** * Returns any additional, general comments recorded for this MarkedIndividual as a whole. * * @return a String of comments */ public String getComments() { if (comments != null) { return comments; } else { return "None"; } } /** * Adds any general comments recorded for this MarkedIndividual as a whole. * * @return a String of comments */ public void addComments(String newComments) { if ((comments != null) && (!(comments.equals("None")))) { comments += newComments; } else { comments = newComments; } } /** * Returns the complete Vector of stored satellite tag data files for this MarkedIndividual. * * @return a Vector of Files * @see java.util.Vector */ public Vector getDataFiles() { return dataFiles; } /** * Returns the sex of this MarkedIndividual. * * @return a String */ public String getSex() { return sex; } /** * Sets the sex of this MarkedIndividual. */ public void setSex(String newSex) { if (newSex != null) { sex = newSex; } else { sex = null; } } public String getGenus() { return genus; } public void setGenus(String newGenus) { genus = newGenus; } public String getSpecificEpithet() { return specificEpithet; } public void setSpecificEpithet(String newEpithet) { specificEpithet = newEpithet; } public String getTaxonomyString() { return Util.taxonomyString(getGenus(), getSpecificEpithet()); } ///this is really only for when dont have a value set; i.e. it should not be run after set on the instance; /// therefore we dont allow that unless you pass boolean true to force it /// TODO we only pick first one - perhaps smarter would be to check all encounters and pick dominant one? public String setTaxonomyFromEncounters(boolean force) { if (!force && ((genus != null) || (specificEpithet != null))) return getTaxonomyString(); if ((encounters == null) || (encounters.size() < 1)) return getTaxonomyString(); for (Encounter enc : encounters) { if ((enc.getGenus() != null) && (enc.getSpecificEpithet() != null)) { genus = enc.getGenus(); specificEpithet = enc.getSpecificEpithet(); return getTaxonomyString(); } } return getTaxonomyString(); } public String setTaxonomyFromEncounters() { return setTaxonomyFromEncounters(false); } //similar to above public String setSexFromEncounters(boolean force) { if (!force && (sex != null)) return getSex(); if ((encounters == null) || (encounters.size() < 1)) return getSex(); for (Encounter enc : encounters) { if (enc.getSex() != null) { sex = enc.getSex(); return getSex(); } } return getSex(); } public String setSexFromEncounters() { return setSexFromEncounters(false); } public double getLastEstimatedSize() { double lastSize = 0; for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getSizeAsDouble() != null) && (temp.getSize() > lastSize)) { lastSize = temp.getSize(); } } return lastSize; } public boolean wasSightedInLocationCode(String locationCode) { for (int c = 0; c < encounters.size(); c++) { try { Encounter temp = (Encounter) encounters.get(c); if ((temp.getLocationID() != null) && (!temp.getLocationID().trim().equals("")) && (temp.getLocationID().trim().equals(locationCode))) { return true; } } catch (NullPointerException npe) { return false; } } return false; } public ArrayList<String> participatesInTheseVerbatimEventDates() { ArrayList<String> vbed = new ArrayList<String>(); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getVerbatimEventDate() != null) && (!vbed.contains(temp.getVerbatimEventDate()))) { vbed.add(temp.getVerbatimEventDate()); } } return vbed; } public ArrayList<String> participatesInTheseLocationIDs() { ArrayList<String> vbed = new ArrayList<String>(); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getLocationID() != null) && (!vbed.contains(temp.getLocationID()))) { vbed.add(temp.getLocationID()); } } return vbed; } public int getNumberLocations() { return this.numberLocations; } public int refreshNumberLocations() { this.numberLocations = this.participatesInTheseLocationIDs().size(); return this.numberLocations; } public boolean wasSightedInVerbatimEventDate(String ved) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getVerbatimEventDate() != null) && (temp.getVerbatimEventDate().equals(ved))) { return true; } } return false; } public boolean wasSightedByUser(String user) { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getSubmitterID() != null) && (temp.getSubmitterID().equals(user))) { return true; } } return false; } public int getMaxNumYearsBetweenSightings() { return maxYearsBetweenResightings; } public int getEarliestSightingYear() { int lowestYear = 5000; for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() < lowestYear) && (temp.getYear() > 0)) { lowestYear = temp.getYear(); } } return lowestYear; } public long getEarliestSightingTime() { long lowestTime = GregorianCalendar.getInstance().getTimeInMillis(); for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getDateInMilliseconds() != null) && (temp.getDateInMilliseconds() < lowestTime) && (temp.getYear() > 0)) lowestTime = temp.getDateInMilliseconds(); } return lowestTime; } public String getSeriesCode() { return seriesCode; } public Vector getInterestedResearchers() { return interestedResearchers; } public void addInterestedResearcher(String email) { if (interestedResearchers == null) { interestedResearchers = new Vector(); } interestedResearchers.add(email); } public void removeInterestedResearcher(String email) { if (interestedResearchers != null) { for (int i = 0; i < interestedResearchers.size(); i++) { String rName = (String) interestedResearchers.get(i); if (rName.equals(email)) { interestedResearchers.remove(i); } } } } public void setSeriesCode(String newCode) { seriesCode = newCode; } /** * Adds a satellite tag data file for this MarkedIndividual. * * @param dataFile the satellite tag data file to be added */ public void addDataFile(String dataFile) { if (dataFiles == null) { dataFiles = new Vector(); } dataFiles.add(dataFile); } /** * Removes a satellite tag data file for this MarkedIndividual. * * @param dataFile The satellite data file, as a String, to be removed. */ public void removeDataFile(String dataFile) { if (dataFiles != null) { dataFiles.remove(dataFile); } } public int getNumberTrainableEncounters() { int count = 0; for (int iter = 0; iter < encounters.size(); iter++) { Encounter enc = (Encounter) encounters.get(iter); if ((enc.getSpots() != null) && (enc.getSpots().size() > 0)) { count++; } } return count; } public int getNumberRightTrainableEncounters() { int count = 0; for (int iter = 0; iter < encounters.size(); iter++) { Encounter enc = (Encounter) encounters.get(iter); if (enc.getRightSpots().size() > 0) { count++; } } return count; } public Vector getTrainableEncounters() { int count = 0; Vector results = new Vector(); for (int iter = 0; iter < encounters.size(); iter++) { Encounter enc = (Encounter) encounters.get(iter); if (enc.getSpots().size() > 0) { results.add(enc); } } return results; } public Vector getRightTrainableEncounters() { int count = 0; Vector results = new Vector(); for (int iter = 0; iter < encounters.size(); iter++) { Encounter enc = (Encounter) encounters.get(iter); if (enc.getRightSpots().size() > 0) { results.add(enc); } } return results; } /*public int getFirstTrainingEncounter() { for(int iter=0;iter<encounters.size(); iter++) { encounter enc=(encounter)encounters.get(iter); if (enc.getSpots()!=null) {return iter;} } return 0; }*/ /*public int getSecondTrainingEncounter() { for(int iter=(getFirstTrainingEncounter()+1);iter<encounters.size(); iter++) { encounter enc=(encounter)encounters.get(iter); if (enc.getSpots()!=null) {return iter;} } return 0; }*/ //months 1-12, days, 1-31 /** * * * @deprecated */ public double avgLengthInPeriod(int m_startYear, int m_startMonth, int m_endYear, int m_endMonth) { double avgLength = 0; int numMeasurements = 0; int endYear = m_endYear; int endMonth = m_endMonth; int startYear = m_startYear; int startMonth = m_startMonth; //test that start and end dates are not reversed if (endYear < startYear) { endYear = m_startYear; endMonth = m_startMonth; startYear = m_endYear; startMonth = m_endMonth; } else if ((endYear == startYear) && (endMonth < startMonth)) { endYear = m_startYear; endMonth = m_startMonth; startYear = m_endYear; startMonth = m_endMonth; } for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() > startYear) && (temp.getYear() < endYear)) { if ((temp.getSizeAsDouble() != null) && (temp.getSize() > 0)) { avgLength += temp.getSize(); numMeasurements++; } } else if ((temp.getYear() == startYear) && (temp.getYear() < endYear) && (temp.getMonth() >= startMonth)) { if ((temp.getSizeAsDouble() != null) && (temp.getSize() > 0)) { avgLength += temp.getSize(); numMeasurements++; } } else if ((temp.getYear() > startYear) && (temp.getYear() == endYear) && (temp.getMonth() <= endMonth)) { if ((temp.getSizeAsDouble() != null) && (temp.getSize() > 0)) { avgLength += temp.getSize(); numMeasurements++; } } else if ((temp.getYear() >= startYear) && (temp.getYear() <= endYear) && (temp.getMonth() >= startMonth) && (temp.getMonth() <= endMonth)) { if ((temp.getSizeAsDouble() != null) && (temp.getSize() > 0)) { avgLength += temp.getSize(); numMeasurements++; } } } if (numMeasurements > 0) { return (avgLength / numMeasurements); } else { return 0.0; } } public Double getAverageMeasurementInPeriod(int m_startYear, int m_startMonth, int m_endYear, int m_endMonth, String measurementType) { double avgMeasurement = 0; int numMeasurements = 0; int endYear = m_endYear; int endMonth = m_endMonth; int startYear = m_startYear; int startMonth = m_startMonth; //test that start and end dates are not reversed if (endYear < startYear) { endYear = m_startYear; endMonth = m_startMonth; startYear = m_endYear; startMonth = m_endMonth; } else if ((endYear == startYear) && (endMonth < startMonth)) { endYear = m_startYear; endMonth = m_startMonth; startYear = m_endYear; startMonth = m_endMonth; } for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.hasMeasurement(measurementType)) { List<Measurement> measures = temp.getMeasurements(); if ((temp.getYear() > startYear) && (temp.getYear() < endYear)) { if (temp.getMeasurement(measurementType) != null) { avgMeasurement += temp.getMeasurement(measurementType).getValue(); numMeasurements++; } } else if ((temp.getYear() == startYear) && (temp.getYear() < endYear) && (temp.getMonth() >= startMonth)) { if (temp.getMeasurement(measurementType) != null) { avgMeasurement += temp.getMeasurement(measurementType).getValue(); numMeasurements++; } } else if ((temp.getYear() > startYear) && (temp.getYear() == endYear) && (temp.getMonth() <= endMonth)) { if (temp.getMeasurement(measurementType) != null) { avgMeasurement += temp.getMeasurement(measurementType).getValue(); numMeasurements++; } } else if ((temp.getYear() >= startYear) && (temp.getYear() <= endYear) && (temp.getMonth() >= startMonth) && (temp.getMonth() <= endMonth)) { if (temp.getMeasurement(measurementType) != null) { avgMeasurement += temp.getMeasurement(measurementType).getValue(); numMeasurements++; } } } } if (numMeasurements > 0) { return (new Double(avgMeasurement / numMeasurements)); } else { return null; } } public Double getAverageBiologicalMeasurementInPeriod(int m_startYear, int m_startMonth, int m_endYear, int m_endMonth, String measurementType) { double avgMeasurement = 0; int numMeasurements = 0; int endYear = m_endYear; int endMonth = m_endMonth; int startYear = m_startYear; int startMonth = m_startMonth; //test that start and end dates are not reversed if (endYear < startYear) { endYear = m_startYear; endMonth = m_startMonth; startYear = m_endYear; startMonth = m_endMonth; } else if ((endYear == startYear) && (endMonth < startMonth)) { endYear = m_startYear; endMonth = m_startMonth; startYear = m_endYear; startMonth = m_endMonth; } for (int c = 0; c < encounters.size(); c++) { Encounter enc = (Encounter) encounters.get(c); if ((enc.getTissueSamples() != null) && (enc.getTissueSamples().size() > 0)) { List<TissueSample> samples = enc.getTissueSamples(); int numTissueSamples = samples.size(); for (int h = 0; h < numTissueSamples; h++) { TissueSample temp = samples.get(h); if (temp.hasMeasurement(measurementType)) { List<BiologicalMeasurement> measures = temp.getBiologicalMeasurements(); if ((enc.getYear() > startYear) && (enc.getYear() < endYear)) { if (temp.getBiologicalMeasurement(measurementType) != null) { avgMeasurement += temp.getBiologicalMeasurement(measurementType).getValue(); numMeasurements++; } } else if ((enc.getYear() == startYear) && (enc.getYear() < endYear) && (enc.getMonth() >= startMonth)) { if (temp.getBiologicalMeasurement(measurementType) != null) { avgMeasurement += temp.getBiologicalMeasurement(measurementType).getValue(); numMeasurements++; } } else if ((enc.getYear() > startYear) && (enc.getYear() == endYear) && (enc.getMonth() <= endMonth)) { if (temp.getBiologicalMeasurement(measurementType) != null) { avgMeasurement += temp.getBiologicalMeasurement(measurementType).getValue(); numMeasurements++; } } else if ((enc.getYear() >= startYear) && (enc.getYear() <= endYear) && (enc.getMonth() >= startMonth) && (enc.getMonth() <= endMonth)) { if (temp.getBiologicalMeasurement(measurementType) != null) { avgMeasurement += temp.getBiologicalMeasurement(measurementType).getValue(); numMeasurements++; } } } } } } if (numMeasurements > 0) { return (new Double(avgMeasurement / numMeasurements)); } else { return null; } } public String getDateTimeCreated() { if (dateTimeCreated != null) { return dateTimeCreated; } return ""; } public String getDateLatestSighting() { if (dateTimeLatestSighting != null) { return dateTimeLatestSighting; } return ""; } public void setDateTimeCreated(String time) { dateTimeCreated = time; } public void setDateTimeLatestSighting(String time) { dateTimeLatestSighting = time; } public void setAlternateID(String newID) { this.alternateid = newID; } public String getAlternateID() { if (alternateid == null) { return "None"; } return alternateid; } /* * Returns a bracketed, comma-delimited string of all of the alternateIDs registered for this marked individual, including those only assigned at the Encounter level */ public String getAllAlternateIDs() { ArrayList<String> allIDs = new ArrayList<String>(); //add any alt IDs for the individual itself if (alternateid != null) { allIDs.add(alternateid); } //add an alt IDs for the individual's encounters int numEncs = encounters.size(); for (int c = 0; c < numEncs; c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getAlternateID() != null) && (!temp.getAlternateID().equals("None")) && (!allIDs.contains(temp.getAlternateID()))) { allIDs.add(temp.getAlternateID()); } } return allIDs.toString(); } public String getDynamicProperties() { return dynamicProperties; } public void setDynamicProperty(String name, String value) { name = name.replaceAll(";", "_").trim().replaceAll("%20", " "); value = value.replaceAll(";", "_").trim(); if (dynamicProperties == null) { dynamicProperties = name + "=" + value + ";"; } else { //let's create a TreeMap of the properties TreeMap<String, String> tm = new TreeMap<String, String>(); StringTokenizer st = new StringTokenizer(dynamicProperties, ";"); while (st.hasMoreTokens()) { String token = st.nextToken(); int equalPlace = token.indexOf("="); tm.put(token.substring(0, equalPlace), token.substring(equalPlace + 1)); } if (tm.containsKey(name)) { tm.remove(name); tm.put(name, value); //now let's recreate the dynamicProperties String String newProps = tm.toString(); int stringSize = newProps.length(); dynamicProperties = newProps.substring(1, (stringSize - 1)).replaceAll(", ", ";") + ";"; } else { dynamicProperties = dynamicProperties + name + "=" + value + ";"; } } } public String getDynamicPropertyValue(String name) { if (dynamicProperties != null) { name = name.replaceAll("%20", " "); //let's create a TreeMap of the properties TreeMap<String, String> tm = new TreeMap<String, String>(); StringTokenizer st = new StringTokenizer(dynamicProperties, ";"); while (st.hasMoreTokens()) { String token = st.nextToken(); int equalPlace = token.indexOf("="); try { tm.put(token.substring(0, equalPlace), token.substring(equalPlace + 1)); } catch (IndexOutOfBoundsException ioob) { } } if (tm.containsKey(name)) { return tm.get(name); } } return null; } public void removeDynamicProperty(String name) { name = name.replaceAll(";", "_").trim().replaceAll("%20", " "); if (dynamicProperties != null) { //let's create a TreeMap of the properties TreeMap<String, String> tm = new TreeMap<String, String>(); StringTokenizer st = new StringTokenizer(dynamicProperties, ";"); while (st.hasMoreTokens()) { String token = st.nextToken(); int equalPlace = token.indexOf("="); tm.put(token.substring(0, (equalPlace)), token.substring(equalPlace + 1)); } if (tm.containsKey(name)) { tm.remove(name); //now let's recreate the dynamicProperties String String newProps = tm.toString(); int stringSize = newProps.length(); dynamicProperties = newProps.substring(1, (stringSize - 1)).replaceAll(", ", ";") + ";"; } } } public ArrayList<Keyword> getAllAppliedKeywordNames(Shepherd myShepherd) { ArrayList<Keyword> al = new ArrayList<Keyword>(); int numEncounters = encounters.size(); for (int i = 0; i < numEncounters; i++) { Encounter enc = (Encounter) encounters.get(i); Iterator<Keyword> it = myShepherd.getAllKeywords(); while (it.hasNext()) { Keyword word = it.next(); if (enc.hasKeyword(word) && (!al.contains(word))) { al.add(word); } } } return al; } public ArrayList<TissueSample> getAllTissueSamples() { ArrayList<TissueSample> al = new ArrayList<TissueSample>(); if (encounters != null) { int numEncounters = encounters.size(); for (int i = 0; i < numEncounters; i++) { Encounter enc = (Encounter) encounters.get(i); if (enc.getTissueSamples() != null) { List<TissueSample> list = enc.getTissueSamples(); if (list.size() > 0) { al.addAll(list); } } } return al; } return null; } public ArrayList<SinglePhotoVideo> getAllSinglePhotoVideo() { ArrayList<SinglePhotoVideo> al = new ArrayList<SinglePhotoVideo>(); int numEncounters = encounters.size(); for (int i = 0; i < numEncounters; i++) { Encounter enc = (Encounter) encounters.get(i); if (enc.getSinglePhotoVideo() != null) { List<SinglePhotoVideo> list = enc.getSinglePhotoVideo(); if (list.size() > 0) { al.addAll(list); } } } return al; } public ArrayList<String> getAllValuesForDynamicProperty(String propertyName) { ArrayList<String> listPropertyValues = new ArrayList<String>(); //first, check if the individual has the property applied if (getDynamicPropertyValue(propertyName) != null) { listPropertyValues.add(getDynamicPropertyValue(propertyName)); } //next check the encounters int numEncounters = encounters.size(); for (int i = 0; i < numEncounters; i++) { Encounter enc = (Encounter) encounters.get(i); if (enc.getDynamicPropertyValue(propertyName) != null) { listPropertyValues.add(enc.getDynamicPropertyValue(propertyName)); } } return listPropertyValues; } /** Returns the patterning type evident on this MarkedIndividual instance. */ public String getPatterningCode() { int numEncs = encounters.size(); for (int i = 0; i < numEncs; i++) { Encounter enc = (Encounter) encounters.get(i); if (enc.getPatterningCode() != null) { return enc.getPatterningCode(); } } return null; } /** Sets the patterning type evident on this MarkedIndividual instance. */ public void setPatterningCode(String newCode) { this.patterningCode = newCode; } public void resetMaxNumYearsBetweenSightings() { int maxYears = 0; int lowestYear = 3000; int highestYear = 0; for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getYear() < lowestYear) && (temp.getYear() > 0)) lowestYear = temp.getYear(); if (temp.getYear() > highestYear) highestYear = temp.getYear(); maxYears = highestYear - lowestYear; if (maxYears < 0) { maxYears = 0; } } maxYearsBetweenResightings = maxYears; } public String sidesSightedInPeriod(int m_startYear, int m_startMonth, int m_startDay, int m_endYear, int m_endMonth, int m_endDay, String locCode) { int endYear = m_endYear; int endMonth = m_endMonth; int endDay = m_endDay; int startYear = m_startYear; int startMonth = m_startMonth; int startDay = m_startDay; GregorianCalendar gcMin = new GregorianCalendar(startYear, startMonth - 1, startDay); GregorianCalendar gcMax = new GregorianCalendar(endYear, endMonth - 1, endDay); boolean left = false; boolean right = false; boolean leftRightTogether = false; for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.getLocationCode().startsWith(locCode)) { if ((temp.getDateInMilliseconds() != null) && (temp.getDateInMilliseconds() >= gcMin.getTimeInMillis()) && (temp.getDateInMilliseconds() <= gcMax.getTimeInMillis())) { if (temp.getNumRightSpots() > 0) { right = true; } if (temp.getNumSpots() > 0) { left = true; } if ((temp.getNumRightSpots() > 0) && (temp.getNumSpots() > 0)) { leftRightTogether = true; } } } } if (leftRightTogether) { return "3"; } else if (left && right) { return "4"; } else if (left) { return "1"; } else if (right) { return "2"; } else { return "0"; } } public String getGenusSpecies() { return getTaxonomyString(); } /** Returns the first haplotype found in the Encounter objects for this MarkedIndividual. @return a String if found or null if no haplotype is found */ public String getHaplotype() { return localHaplotypeReflection; } public String getGeneticSex() { for (int c = 0; c < encounters.size(); c++) { Encounter temp = (Encounter) encounters.get(c); if (temp.getGeneticSex() != null) { return temp.getGeneticSex(); } } return null; } public boolean hasLocusAndAllele(String locus, Integer alleleValue) { ArrayList<TissueSample> samples = getAllTissueSamples(); int numSamples = samples.size(); for (int i = 0; i < numSamples; i++) { TissueSample sample = samples.get(i); if (sample.getGeneticAnalyses() != null) { List<GeneticAnalysis> analyses = sample.getGeneticAnalyses(); int numAnalyses = analyses.size(); for (int e = 0; e < numAnalyses; e++) { GeneticAnalysis ga = analyses.get(e); if (ga.getAnalysisType().equals("MicrosatelliteMarkers")) { MicrosatelliteMarkersAnalysis msa = (MicrosatelliteMarkersAnalysis) ga; if (msa.getLocus(locus) != null) { Locus l = msa.getLocus(locus); if (l.hasAllele(alleleValue)) { return true; } } } } } } return false; } public ArrayList<Integer> getAlleleValuesForLocus(String locus) { ArrayList<Integer> matchingValues = new ArrayList<Integer>(); ArrayList<TissueSample> samples = getAllTissueSamples(); int numSamples = samples.size(); for (int i = 0; i < numSamples; i++) { TissueSample sample = samples.get(i); if (sample.getGeneticAnalyses() != null) { List<GeneticAnalysis> analyses = sample.getGeneticAnalyses(); int numAnalyses = analyses.size(); for (int e = 0; e < numAnalyses; e++) { GeneticAnalysis ga = analyses.get(e); if (ga.getAnalysisType().equals("MicrosatelliteMarkers")) { MicrosatelliteMarkersAnalysis msa = (MicrosatelliteMarkersAnalysis) ga; if (msa.getLocus(locus) != null) { Locus l = msa.getLocus(locus); if ((l.getAllele0() != null)) { matchingValues.add(l.getAllele0()); } if ((l.getAllele1() != null)) { matchingValues.add(l.getAllele1()); } if ((l.getAllele2() != null)) { matchingValues.add(l.getAllele2()); } if ((l.getAllele3() != null)) { matchingValues.add(l.getAllele3()); } } } } } } return matchingValues; } public boolean hasLocus(String locus) { ArrayList<TissueSample> samples = getAllTissueSamples(); int numSamples = samples.size(); for (int i = 0; i < numSamples; i++) { TissueSample sample = samples.get(i); if (sample.getGeneticAnalyses() != null) { List<GeneticAnalysis> analyses = sample.getGeneticAnalyses(); int numAnalyses = analyses.size(); for (int e = 0; e < numAnalyses; e++) { GeneticAnalysis ga = analyses.get(e); if (ga.getAnalysisType().equals("MicrosatelliteMarkers")) { MicrosatelliteMarkersAnalysis msa = (MicrosatelliteMarkersAnalysis) ga; if (msa.getLocus(locus) != null) { return true; } } } } } return false; } public boolean hasMsMarkers() { ArrayList<TissueSample> samples = getAllTissueSamples(); if (samples != null) { int numSamples = samples.size(); for (int i = 0; i < numSamples; i++) { TissueSample sample = samples.get(i); if (sample.getGeneticAnalyses() != null) { List<GeneticAnalysis> analyses = sample.getGeneticAnalyses(); int numAnalyses = analyses.size(); for (int e = 0; e < numAnalyses; e++) { GeneticAnalysis ga = analyses.get(e); if (ga.getAnalysisType().equals("MicrosatelliteMarkers")) { return true; } } } } } return false; } public boolean hasGeneticSex() { ArrayList<TissueSample> samples = getAllTissueSamples(); int numSamples = samples.size(); for (int i = 0; i < numSamples; i++) { TissueSample sample = samples.get(i); if (sample.getGeneticAnalyses() != null) { List<GeneticAnalysis> analyses = sample.getGeneticAnalyses(); int numAnalyses = analyses.size(); for (int e = 0; e < numAnalyses; e++) { GeneticAnalysis ga = analyses.get(e); if (ga.getAnalysisType().equals("SexAnalysis")) { return true; } } } } return false; } /** *Obtains the email addresses of all submitters, photographs, and others to notify. *@return ArrayList of all emails to inform */ public List<String> getAllEmailsToUpdate() { ArrayList notifyUs = new ArrayList(); int numEncounters = encounters.size(); //int numUnidetifiableEncounters=unidentifiableEncounters.size(); //process encounters for (int i = 0; i < numEncounters; i++) { Encounter enc = (Encounter) encounters.get(i); if ((enc.getSubmitterEmail() != null) && (!enc.getSubmitterEmail().trim().equals(""))) { String submitter = enc.getSubmitterEmail(); if (submitter.indexOf(",") != -1) { StringTokenizer str = new StringTokenizer(submitter, ","); while (str.hasMoreTokens()) { String token = str.nextToken().trim(); if ((!token.equals("")) && (!notifyUs.contains(token))) { notifyUs.add(token); } } } else { if (!notifyUs.contains(submitter)) { notifyUs.add(submitter); } } } if ((enc.getPhotographerEmail() != null) && (!enc.getPhotographerEmail().trim().equals(""))) { String photog = enc.getPhotographerEmail(); if (photog.indexOf(",") != -1) { StringTokenizer str = new StringTokenizer(photog, ","); while (str.hasMoreTokens()) { String token = str.nextToken().trim(); if ((!token.equals("")) && (!notifyUs.contains(token))) { notifyUs.add(token); } } } else { if (!notifyUs.contains(photog)) { notifyUs.add(photog); } } } if ((enc.getInformOthers() != null) && (!enc.getInformOthers().trim().equals(""))) { String photog = enc.getInformOthers(); if (photog.indexOf(",") != -1) { StringTokenizer str = new StringTokenizer(photog, ","); while (str.hasMoreTokens()) { String token = str.nextToken().trim(); if ((!token.equals("")) && (!notifyUs.contains(token))) { notifyUs.add(token); } } } else { if (!notifyUs.contains(photog)) { notifyUs.add(photog); } } } } /* //process log encounters for(int i=0;i<numUnidentifiableEncounters;i++){ Encounter enc=(Encounter)unidentifiableEncounters.get(i); if((enc.getSubmitterEmail()!=null)&&(!enc.getSubmitterEmail().trim().equals(""))){ String submitter = enc.getSubmitterEmail(); if (submitter.indexOf(",") != -1) { StringTokenizer str = new StringTokenizer(submitter, ","); while (str.hasMoreTokens()) { String token = str.nextToken().trim(); if((!token.equals(""))&&(!notifyUs.contains(token))){notifyUs.add(token);} } } else{if(!notifyUs.contains(submitter)){notifyUs.add(submitter);}} } if((enc.getPhotographerEmail()!=null)&&(!enc.getPhotographerEmail().trim().equals(""))){ String photog = enc.getPhotographerEmail(); if (photog.indexOf(",") != -1) { StringTokenizer str = new StringTokenizer(photog, ","); while (str.hasMoreTokens()) { String token = str.nextToken().trim(); if((!token.equals(""))&&(!notifyUs.contains(token))){notifyUs.add(token);} } } else{if(!notifyUs.contains(photog)){notifyUs.add(photog);}} } if((enc.getInformOthers()!=null)&&(!enc.getInformOthers().trim().equals(""))){ String photog = enc.getInformOthers(); if (photog.indexOf(",") != -1) { StringTokenizer str = new StringTokenizer(photog, ","); while (str.hasMoreTokens()) { String token = str.nextToken().trim(); if((!token.equals(""))&&(!notifyUs.contains(token))){notifyUs.add(token);} } } else{if(!notifyUs.contains(photog)){notifyUs.add(photog);}} } } */ return notifyUs; } //public void removeLogEncounter(Encounter enc){if(unidentifiableEncounters.contains(enc)){unidentifiableEncounters.remove(enc);}} public float distFrom(float lat1, float lng1, float lat2, float lng2) { double earthRadius = 3958.75; double dLat = Math.toRadians(lat2 - lat1); double dLng = Math.toRadians(lng2 - lng1); double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double dist = earthRadius * c; int meterConversion = 1609; return new Float(dist * meterConversion).floatValue(); } public Float getMaxDistanceBetweenTwoSightings() { int numEncs = encounters.size(); Float maxDistance = new Float(0); if (numEncs > 1) { for (int y = 0; y < numEncs; y++) { Encounter thisEnc = (Encounter) encounters.get(y); if ((thisEnc.getLatitudeAsDouble() != null) && (thisEnc.getLongitudeAsDouble() != null)) { for (int z = (y + 1); z < numEncs; z++) { Encounter nextEnc = (Encounter) encounters.get(z); if ((nextEnc.getLatitudeAsDouble() != null) && (nextEnc.getLongitudeAsDouble() != null)) { try { Float tempMaxDistance = distFrom(new Float(thisEnc.getLatitudeAsDouble()), new Float(thisEnc.getLongitudeAsDouble()), new Float(nextEnc.getLatitudeAsDouble()), new Float(nextEnc.getLongitudeAsDouble())); if (tempMaxDistance > maxDistance) { maxDistance = tempMaxDistance; } } catch (Exception e) { e.printStackTrace(); System.out.println("Hit an NPE when calculating distance between: " + thisEnc.getCatalogNumber() + " and " + nextEnc.getCatalogNumber()); } } } } } } return maxDistance; } public long getMaxTimeBetweenTwoSightings() { int numEncs = encounters.size(); long maxTime = 0; if (numEncs > 1) { for (int y = 0; y < numEncs; y++) { Encounter thisEnc = (Encounter) encounters.get(y); for (int z = (y + 1); z < numEncs; z++) { Encounter nextEnc = (Encounter) encounters.get(z); if ((thisEnc.getDateInMilliseconds() != null) && (nextEnc.getDateInMilliseconds() != null)) { long tempMaxTime = Math.abs(thisEnc.getDateInMilliseconds().longValue() - nextEnc.getDateInMilliseconds().longValue()); if (tempMaxTime > maxTime) { maxTime = tempMaxTime; } } } } } return maxTime; } public ArrayList<String> getAllAssignedUsers() { ArrayList<String> allIDs = new ArrayList<String>(); //add an alt IDs for the individual's encounters int numEncs = encounters.size(); for (int c = 0; c < numEncs; c++) { Encounter temp = (Encounter) encounters.get(c); if ((temp.getAssignedUsername() != null) && (!allIDs.contains(temp.getAssignedUsername()))) { allIDs.add(temp.getAssignedUsername()); } } return allIDs; } /** * DO NOT SET DIRECTLY!! * * @param myDepth */ public void doNotSetLocalHaplotypeReflection(String myHaplo) { if (myHaplo != null) { localHaplotypeReflection = myHaplo; } else { localHaplotypeReflection = null; } } public long getTimeOfBirth() { return timeOfBirth; } public long getTimeofDeath() { return timeOfDeath; } public void setTimeOfBirth(long newTime) { timeOfBirth = newTime; } public void setTimeOfDeath(long newTime) { timeOfDeath = newTime; } public List<Relationship> getAllRelationships(Shepherd myShepherd) { return myShepherd.getAllRelationshipsForMarkedIndividual(individualID); } public String getFomattedMSMarkersString(String[] loci) { StringBuffer sb = new StringBuffer(); int numLoci = loci.length; for (int i = 0; i < numLoci; i++) { ArrayList<Integer> alleles = getAlleleValuesForLocus(loci[i]); if ((alleles.size() > 0) && (alleles.get(0) != null)) { sb.append(alleles.get(0) + " "); } else { sb.append("--- "); } if ((alleles.size() >= 2) && (alleles.get(1) != null)) { sb.append(alleles.get(1) + " "); } else { sb.append("--- "); } } return sb.toString(); } public Float getMinDistanceBetweenTwoMarkedIndividuals(MarkedIndividual otherIndy) { DecimalFormat df = new DecimalFormat("#.#"); Float minDistance = new Float(1000000); if ((encounters != null) && (encounters.size() > 0) && (otherIndy.getEncounters() != null) && (otherIndy.getEncounters().size() > 0)) { int numEncs = encounters.size(); int numOtherEncs = otherIndy.getEncounters().size(); if (numEncs > 0) { for (int y = 0; y < numEncs; y++) { Encounter thisEnc = (Encounter) encounters.get(y); if ((thisEnc.getLatitudeAsDouble() != null) && (thisEnc.getLongitudeAsDouble() != null)) { for (int z = 0; z < numOtherEncs; z++) { Encounter nextEnc = otherIndy.getEncounter(z); if ((nextEnc.getLatitudeAsDouble() != null) && (nextEnc.getLongitudeAsDouble() != null)) { try { Float tempMinDistance = distFrom(new Float(thisEnc.getLatitudeAsDouble()), new Float(thisEnc.getLongitudeAsDouble()), new Float(nextEnc.getLatitudeAsDouble()), new Float(nextEnc.getLongitudeAsDouble())); if (tempMinDistance < minDistance) { minDistance = tempMinDistance; } } catch (Exception e) { e.printStackTrace(); System.out.println("Hit an NPE when calculating distance between: " + thisEnc.getCatalogNumber() + " and " + nextEnc.getCatalogNumber()); } } } } } } } if (minDistance > 999999) minDistance = new Float(-1); return minDistance; } //convenience function to Collaboration permissions public boolean canUserAccess(HttpServletRequest request) { return Collaboration.canUserAccessMarkedIndividual(this, request); } public JSONObject sanitizeJson(HttpServletRequest request, JSONObject jobj) throws JSONException { if (this.canUserAccess(request)) return jobj; jobj.remove("numberLocations"); jobj.remove("sex"); jobj.remove("numberEncounters"); jobj.remove("timeOfDeath"); jobj.remove("timeOfBirth"); jobj.remove("maxYearsBetweenResightings"); //jobj.remove("numUnidentifiableEncounters"); jobj.remove("nickName"); jobj.remove("nickNamer"); jobj.put("_sanitized", true); return jobj; } // Returns a somewhat rest-like JSON object containing the metadata public JSONObject uiJson(HttpServletRequest request) throws JSONException { JSONObject jobj = new JSONObject(); jobj.put("individualID", this.getIndividualID()); jobj.put("url", this.getUrl(request)); jobj.put("sex", this.getSex()); jobj.put("nickname", this.nickName); Vector<String> encIDs = new Vector<String>(); for (Encounter enc : this.encounters) { encIDs.add(enc.getCatalogNumber()); } jobj.put("encounterIDs", encIDs.toArray()); return sanitizeJson(request, jobj); } public String getUrl(HttpServletRequest request) { return request.getScheme() + "://" + CommonConfiguration.getURLLocation(request) + "/individuals.jsp?number=" + this.getIndividualID(); } /** * returns an array of the MediaAsset sanitized JSON, because whenever UI queries our DB (regardless of class query), * all they want in return are MediaAssets * TODO: decorate with metadata **/ public org.datanucleus.api.rest.orgjson.JSONArray sanitizeMedia(HttpServletRequest request) throws org.datanucleus.api.rest.orgjson.JSONException { org.datanucleus.api.rest.orgjson.JSONArray resultArray = new org.datanucleus.api.rest.orgjson.JSONArray(); for (int i = 0; i < encounters.size(); i++) { Encounter tempEnc = (Encounter) encounters.get(i); Util.concatJsonArrayInPlace(resultArray, tempEnc.sanitizeMedia(request)); } return resultArray; } public ArrayList<org.datanucleus.api.rest.orgjson.JSONObject> getExemplarImages(HttpServletRequest req) throws JSONException { ArrayList<org.datanucleus.api.rest.orgjson.JSONObject> al = new ArrayList<org.datanucleus.api.rest.orgjson.JSONObject>(); //boolean haveProfilePhoto=false; for (Encounter enc : this.getDateSortedEncounters()) { //if((enc.getDynamicPropertyValue("PublicView")==null)||(enc.getDynamicPropertyValue("PublicView").equals("Yes"))){ ArrayList<Annotation> anns = enc.getAnnotations(); if ((anns == null) || (anns.size() < 1)) { continue; } for (Annotation ann : anns) { //if (!ann.isTrivial()) continue; MediaAsset ma = ann.getMediaAsset(); if (ma != null) { //JSONObject j = new JSONObject(); JSONObject j = ma.sanitizeJson(req, new JSONObject()); if ((j != null) && (ma.getMimeTypeMajor() != null) && (ma.getMimeTypeMajor().equals("image"))) { //ok, we have a viable candidate //put ProfilePhotos at the beginning if (ma.hasKeyword("ProfilePhoto")) { al.add(0, j); } //do nothing and don't include it if it has NoProfilePhoto keyword else if (ma.hasKeyword("NoProfilePhoto")) { } //otherwise, just add it to the bottom of the stack else { al.add(j); } } } } //} } return al; } public org.datanucleus.api.rest.orgjson.JSONObject getExemplarImage(HttpServletRequest req) throws JSONException { ArrayList<org.datanucleus.api.rest.orgjson.JSONObject> al = getExemplarImages(req); if (al.size() > 0) { return al.get(0); } return new JSONObject(); } // WARNING! THIS IS ONLY CORRECT IF ITS LOGIC CORRESPONDS TO getExemplarImage public String getExemplarPhotographer() { for (Encounter enc : this.getDateSortedEncounters()) { if ((enc.getDynamicPropertyValue("PublicView") == null) || (enc.getDynamicPropertyValue("PublicView").equals("Yes"))) { if ((enc.getDynamicPropertyValue("ShowPhotographer") == null) || (enc.getDynamicPropertyValue("ShowPhotographer").equals("Yes"))) { return enc.getPhotographerName(); } else { return ""; } } } return ""; } //this simple version makes some assumptions: you already have list of collabs, and it is not visible public String collaborationLockHtml(HttpServletRequest request) { String context = "context0"; context = ServletUtilities.getContext(request); Shepherd myShepherd = new Shepherd(context); myShepherd.setAction("MarkedIndividual.class"); myShepherd.beginDBTransaction(); List<Collaboration> collabs = Collaboration.collaborationsForCurrentUser(request); ArrayList<String> uids = this.getAllAssignedUsers(); ArrayList<String> open = new ArrayList<String>(); String collabClass = "pending"; String data = ""; for (String u : uids) { Collaboration c = Collaboration.findCollaborationWithUser(u, collabs); if ((c == null) || (c.getState() == null)) { User user = myShepherd.getUser(u); String fullName = u; if (user.getFullName() != null) fullName = user.getFullName(); open.add(u); data += "," + u + ":" + fullName.replace(",", " ").replace(":", " ").replace("\"", " "); } } if (open.size() > 0) { collabClass = "new"; data = data.substring(1); } myShepherd.rollbackDBTransaction(); myShepherd.closeDBTransaction(); return "<div class=\"row-lock " + collabClass + " collaboration-button\" data-multiuser=\"" + data + "\"> </div>"; } public void refreshDependentProperties(String context) { this.refreshNumberEncounters(); this.refreshNumberLocations(); this.resetMaxNumYearsBetweenSightings(); this.refreshDateFirstIdentified(); this.refreshThumbnailUrl(context); this.refreshDateLastestSighting(); } public String toString() { return new ToStringBuilder(this).append("individualID", individualID).append("species", getGenusSpecies()) .append("sex", getSex()).append("numEncounters", numberEncounters) .append("numLocations", numberLocations).toString(); } }