/**\r
-* Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
-* http://www.e-taxonomy.eu\r
-* \r
-* The contents of this file are subject to the Mozilla Public License Version 1.1\r
-* See LICENSE.TXT at the top of this package for the full license terms.\r
-*/\r
+ * Copyright (C) 2007 EDIT\r
+ * European Distributed Institute of Taxonomy \r
+ * http://www.e-taxonomy.eu\r
+ * \r
+ * The contents of this file are subject to the Mozilla Public License Version 1.1\r
+ * See LICENSE.TXT at the top of this package for the full license terms.\r
+ */\r
\r
package eu.etaxonomy.cdm.api.facade;\r
\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
import java.text.ParseException;\r
import java.util.ArrayList;\r
import java.util.HashMap;\r
import java.util.Map;\r
import java.util.Set;\r
\r
-import javax.mail.MethodNotSupportedException;\r
+import javax.persistence.Transient;\r
\r
+import org.apache.commons.lang.StringUtils;\r
import org.apache.log4j.Logger;\r
\r
+import eu.etaxonomy.cdm.api.service.IOccurrenceService;\r
+import eu.etaxonomy.cdm.common.CdmUtils;\r
+import eu.etaxonomy.cdm.common.UTF8;\r
import eu.etaxonomy.cdm.model.agent.AgentBase;\r
+import eu.etaxonomy.cdm.model.agent.Person;\r
+import eu.etaxonomy.cdm.model.common.Annotation;\r
import eu.etaxonomy.cdm.model.common.CdmBase;\r
+import eu.etaxonomy.cdm.model.common.DefinedTerm;\r
+import eu.etaxonomy.cdm.model.common.IOriginalSource;\r
import eu.etaxonomy.cdm.model.common.IdentifiableSource;\r
import eu.etaxonomy.cdm.model.common.Language;\r
import eu.etaxonomy.cdm.model.common.LanguageString;\r
+import eu.etaxonomy.cdm.model.common.OriginalSourceType;\r
import eu.etaxonomy.cdm.model.common.TimePeriod;\r
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
import eu.etaxonomy.cdm.model.description.Feature;\r
-import eu.etaxonomy.cdm.model.description.Sex;\r
import eu.etaxonomy.cdm.model.description.SpecimenDescription;\r
-import eu.etaxonomy.cdm.model.description.Stage;\r
import eu.etaxonomy.cdm.model.description.TextData;\r
import eu.etaxonomy.cdm.model.location.NamedArea;\r
import eu.etaxonomy.cdm.model.location.Point;\r
import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
import eu.etaxonomy.cdm.model.occurrence.Collection;\r
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;\r
-import eu.etaxonomy.cdm.model.occurrence.DerivedUnitBase;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;\r
+import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;\r
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;\r
-import eu.etaxonomy.cdm.model.occurrence.FieldObservation;\r
+import eu.etaxonomy.cdm.model.occurrence.FieldUnit;\r
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;\r
import eu.etaxonomy.cdm.model.occurrence.PreservationMethod;\r
-import eu.etaxonomy.cdm.model.occurrence.Specimen;\r
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;\r
-import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
+import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;\r
+import eu.etaxonomy.cdm.model.reference.Reference;\r
\r
/**\r
* This class is a facade to the eu.etaxonomy.cdm.model.occurrence package from\r
* a specimen based view. It does not support all functionality available in the\r
* occurrence package.<BR>\r
- * The most significant restriction is that a specimen may derive only from\r
- * one direct derivation event and there must be only one field observation (gathering event)\r
- * it derives from.<BR> \r
+ * The most significant restriction is that a specimen may derive only from one\r
+ * direct derivation event and there must be only one field unit\r
+ * (gathering event) it derives from.<BR>\r
* \r
* @author a.mueller\r
* @date 14.05.2010\r
*/\r
public class DerivedUnitFacade {\r
+ @SuppressWarnings("unused")\r
private static final Logger logger = Logger.getLogger(DerivedUnitFacade.class);\r
- \r
+\r
private static final String notSupportMessage = "A specimen facade not supported exception has occurred at a place where this should not have happened. The developer should implement not support check properly during class initialization ";\r
+\r
+ private static final boolean CREATE = true;\r
+ private static final boolean CREATE_NOT = false;\r
+\r
+ private final DerivedUnitFacadeConfigurator config;\r
\r
- \r
- /**\r
- * Enum that defines the class the "Specimen" belongs to.\r
- * Some methods of the facade are not available for certain classes\r
- * and will throw an Exception when invoking them.\r
- */\r
- public enum DerivedUnitType{\r
- Specimen ("Specimen"),\r
- Observation("Observation"),\r
- LivingBeing("Living Being"),\r
- Fossil("Fossil"),\r
- DerivedUnit("Derived Unit");\r
- \r
- String representation;\r
- private DerivedUnitType(String representation){\r
- this.representation = representation;\r
- }\r
- \r
- /**\r
- * @return the representation\r
- */\r
- public String getRepresentation() {\r
- return representation;\r
- }\r
- \r
- private DerivedUnitBase getNewDerivedUnitInstance(){\r
- if (this == DerivedUnitType.Specimen){\r
- return eu.etaxonomy.cdm.model.occurrence.Specimen.NewInstance();\r
- }else if (this == DerivedUnitType.Observation){\r
- return eu.etaxonomy.cdm.model.occurrence.Observation.NewInstance();\r
- }else if (this == DerivedUnitType.LivingBeing){\r
- return eu.etaxonomy.cdm.model.occurrence.LivingBeing.NewInstance();\r
- }else if (this == DerivedUnitType.Fossil){\r
- return eu.etaxonomy.cdm.model.occurrence.Fossil.NewInstance();\r
- }else if (this == DerivedUnitType.DerivedUnit){\r
- return eu.etaxonomy.cdm.model.occurrence.DerivedUnit.NewInstance();\r
- }else{\r
- throw new IllegalStateException("Unknown derived unit type " + this.getRepresentation());\r
- }\r
- }\r
- \r
- }\r
- \r
- \r
- private DerivedUnitFacadeConfigurator config;\r
- \r
- //private GatheringEvent gatheringEvent;\r
- private DerivedUnitType type; //needed?\r
- \r
- private FieldObservation fieldObservation;\r
- \r
- private DerivedUnitBase derivedUnit;\r
+ private Map<PropertyChangeListener, CdmBase> listeners = new HashMap<PropertyChangeListener, CdmBase>();\r
+\r
+ // private GatheringEvent gatheringEvent;\r
+ private SpecimenOrObservationType type; // needed?\r
+\r
+ private FieldUnit fieldUnit;\r
\r
- //media - the text data holding the media\r
+ private final DerivedUnit derivedUnit;\r
+\r
+ // media - the text data holding the media\r
private TextData derivedUnitMediaTextData;\r
private TextData fieldObjectMediaTextData;\r
- \r
- \r
+\r
private TextData ecology;\r
private TextData plantDescription;\r
+\r
+ /**\r
+ * Creates a derived unit facade for a new derived unit of type\r
+ * <code>type</code>.\r
+ * \r
+ * @param type\r
+ * @return\r
+ */\r
+ public static DerivedUnitFacade NewInstance(SpecimenOrObservationType type) {\r
+ return new DerivedUnitFacade(type, null, null);\r
+ }\r
\r
- public static DerivedUnitFacade NewInstance(DerivedUnitType type){\r
- return new DerivedUnitFacade(type);\r
+ /**\r
+ * Creates a derived unit facade for a new derived unit of type\r
+ * <code>type</code>.\r
+ * \r
+ * @param type\r
+ * @return\r
+ */\r
+ public static DerivedUnitFacade NewInstance(SpecimenOrObservationType type, FieldUnit fieldUnit) {\r
+ return new DerivedUnitFacade(type, fieldUnit, null);\r
}\r
\r
- public static DerivedUnitFacade NewInstance(DerivedUnitBase derivedUnit) throws DerivedUnitFacadeNotSupportedException{\r
- return new DerivedUnitFacade(derivedUnit, null, DerivedUnitType.Specimen);\r
+ /**\r
+ * Creates a derived unit facade for a new derived unit of type\r
+ * <code>type</code>.\r
+ * \r
+ * @param type\r
+ * @param fieldUnit the field unit to use\r
+ * @param config the facade configurator to use\r
+ * //TODO are there any ambiguities to solve with defining a field unit or a configurator \r
+ * @return\r
+ */\r
+ public static DerivedUnitFacade NewInstance(SpecimenOrObservationType type, FieldUnit fieldUnit, DerivedUnitFacadeConfigurator config) {\r
+ return new DerivedUnitFacade(type, fieldUnit, config);\r
}\r
+\r
\r
- public static DerivedUnitFacade NewInstance(DerivedUnitBase derivedUnit, DerivedUnitFacadeConfigurator config) throws DerivedUnitFacadeNotSupportedException{\r
- return new DerivedUnitFacade(derivedUnit, config, DerivedUnitType.Specimen);\r
+ /**\r
+ * Creates a derived unit facade for a given derived unit using the default\r
+ * configuration.\r
+ * \r
+ * @param derivedUnit\r
+ * @return\r
+ * @throws DerivedUnitFacadeNotSupportedException\r
+ */\r
+ public static DerivedUnitFacade NewInstance(DerivedUnit derivedUnit)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ return new DerivedUnitFacade(derivedUnit, null);\r
}\r
\r
-// ****************** CONSTRUCTOR ****************************************************\r
- \r
- private DerivedUnitFacade(DerivedUnitType type){\r
- this.config = DerivedUnitFacadeConfigurator.NewInstance();\r
- \r
- //derivedUnit\r
- derivedUnit = type.getNewDerivedUnitInstance();\r
- setCacheStrategy();\r
+ public static DerivedUnitFacade NewInstance(DerivedUnit derivedUnit,\r
+ DerivedUnitFacadeConfigurator config)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ return new DerivedUnitFacade(derivedUnit, config);\r
}\r
- \r
- private DerivedUnitFacade(DerivedUnitBase derivedUnit, DerivedUnitFacadeConfigurator config, DerivedUnitType type) throws DerivedUnitFacadeNotSupportedException{\r
- //this.type = type; ??\r
- \r
+\r
+ // ****************** CONSTRUCTOR ******************************************\r
+\r
+ private DerivedUnitFacade(SpecimenOrObservationType type, FieldUnit fieldUnit, DerivedUnitFacadeConfigurator config) {\r
if (config == null){\r
config = DerivedUnitFacadeConfigurator.NewInstance();\r
}\r
this.config = config;\r
- \r
- //derived unit\r
+ this.type = type;\r
+ // derivedUnit\r
+ derivedUnit = getNewDerivedUnitInstance(type);\r
+ setFieldUnit(fieldUnit);\r
+ if (derivedUnit != null){\r
+ setCacheStrategy();\r
+ }else{\r
+ setFieldUnitCacheStrategy();\r
+ }\r
+ }\r
+\r
+ private DerivedUnit getNewDerivedUnitInstance( SpecimenOrObservationType type) {\r
+ if (type.isFieldUnit()){\r
+ return null;\r
+ }else if(type.isAnyDerivedUnit()){\r
+ return DerivedUnit.NewInstance(type);\r
+ } else {\r
+ String message = "Unknown specimen or observation type %s";\r
+ message = String.format(message, type.getMessage());\r
+ throw new IllegalStateException(message);\r
+ }\r
+ }\r
+\r
+ private DerivedUnitFacade(DerivedUnit derivedUnit, DerivedUnitFacadeConfigurator config)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+\r
+ if (config == null) {\r
+ config = DerivedUnitFacadeConfigurator.NewInstance();\r
+ }\r
+ this.config = config;\r
+\r
+ // derived unit\r
this.derivedUnit = derivedUnit;\r
- setCacheStrategy();\r
+ this.type = derivedUnit.getRecordBasis();\r
\r
- //derivation event\r
- if (this.derivedUnit.getDerivedFrom() != null){\r
- DerivationEvent derivationEvent = getDerivationEvent(true);\r
- //fieldObservation\r
- Set<FieldObservation> fieldOriginals = getFieldObservationsOriginals(derivationEvent, null);\r
- if (fieldOriginals.size() > 1){\r
- throw new DerivedUnitFacadeNotSupportedException("Specimen must not have more than 1 derivation event");\r
- }else if (fieldOriginals.size() == 0){\r
- //fieldObservation = FieldObservation.NewInstance();\r
- }else if (fieldOriginals.size() == 1){\r
- fieldObservation = fieldOriginals.iterator().next();\r
- }else{\r
+ // derivation event\r
+ if (this.derivedUnit.getDerivedFrom() != null) {\r
+ DerivationEvent derivationEvent = getDerivationEvent(CREATE);\r
+ // fieldUnit\r
+ Set<FieldUnit> fieldOriginals = getFieldUnitOriginals(derivationEvent, null);\r
+ if (fieldOriginals.size() > 1) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Specimen must not have more than 1 derivation event");\r
+ } else if (fieldOriginals.size() == 0) {\r
+ // fieldUnit = FieldUnit.NewInstance();\r
+ } else if (fieldOriginals.size() == 1) {\r
+ fieldUnit = fieldOriginals.iterator().next();\r
+ // ###fieldUnit =\r
+ // getInitializedFieldUnit(fieldUnit);\r
+ if (config.isFirePropertyChangeEvents()){\r
+ addNewEventPropagationListener(fieldUnit);\r
+ }\r
+ } else {\r
throw new IllegalStateException("Illegal state");\r
- } \r
+ }\r
}\r
-\r
- //test if unsupported\r
\r
- //media\r
- //specimen\r
-// String objectTypeExceptionText = "Specimen";\r
-// SpecimenDescription imageGallery = getImageGalleryWithSupportTest(derivedUnit, objectTypeExceptionText, false);\r
-// getImageTextDataWithSupportTest(imageGallery, objectTypeExceptionText);\r
- this.derivedUnitMediaTextData = inititialzeTextDataWithSupportTest(Feature.IMAGE(), this.derivedUnit, false, true);\r
- \r
- //field observation\r
-// objectTypeExceptionText = "Field observation";\r
-// imageGallery = getImageGalleryWithSupportTest(fieldObservation, objectTypeExceptionText, false);\r
-// getImageTextDataWithSupportTest(imageGallery, objectTypeExceptionText);\r
+ this.derivedUnitMediaTextData = inititializeTextDataWithSupportTest(Feature.IMAGE(), this.derivedUnit, false, true);\r
+\r
fieldObjectMediaTextData = initializeFieldObjectTextDataWithSupportTest(Feature.IMAGE(), false, true);\r
+\r
\r
- //handle derivedUnit.getMedia()\r
- if (derivedUnit.getMedia().size() > 0){\r
- //TODO better changed model here to allow only one place for images\r
- if (this.config.isMoveDerivedUnitMediaToGallery()){\r
- Set<Media> mediaSet = derivedUnit.getMedia();\r
- for (Media media : mediaSet){\r
- this.addDerivedUnitMedia(media);\r
- }\r
- mediaSet.removeAll(getDerivedUnitMedia());\r
- }else{\r
- throw new DerivedUnitFacadeNotSupportedException("Specimen may not have direct media. Only (one) image gallery is allowed");\r
+//direct media have been removed from specimenorobservationbase #3597\r
+// // handle derivedUnit.getMedia()\r
+// if (derivedUnit.getMedia().size() > 0) {\r
+// // TODO better changed model here to allow only one place for images\r
+// if (this.config.isMoveDerivedUnitMediaToGallery()) {\r
+// Set<Media> mediaSet = derivedUnit.getMedia();\r
+// for (Media media : mediaSet) {\r
+// this.addDerivedUnitMedia(media);\r
+// }\r
+// mediaSet.removeAll(getDerivedUnitMedia());\r
+// } else {\r
+// throw new DerivedUnitFacadeNotSupportedException(\r
+// "Specimen may not have direct media. Only (one) image gallery is allowed");\r
+// }\r
+// }\r
+//\r
+// // handle fieldUnit.getMedia()\r
+// if (fieldUnit != null && fieldUnit.getMedia() != null\r
+// && fieldUnit.getMedia().size() > 0) {\r
+// // TODO better changed model here to allow only one place for images\r
+// if (this.config.isMoveFieldObjectMediaToGallery()) {\r
+// Set<Media> mediaSet = fieldUnit.getMedia();\r
+// for (Media media : mediaSet) {\r
+// this.addFieldObjectMedia(media);\r
+// }\r
+// mediaSet.removeAll(getFieldObjectMedia());\r
+// } else {\r
+// throw new DerivedUnitFacadeNotSupportedException(\r
+// "Field object may not have direct media. Only (one) image gallery is allowed");\r
+// }\r
+// }\r
+\r
+ // test if descriptions are supported\r
+ ecology = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.ECOLOGY(), false, false);\r
+ plantDescription = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.DESCRIPTION(), false, false);\r
+ \r
+ setCacheStrategy();\r
+\r
+ }\r
+\r
+ private DerivedUnit getInitializedDerivedUnit(\r
+ DerivedUnit derivedUnit) {\r
+ IOccurrenceService occurrenceService = this.config\r
+ .getOccurrenceService();\r
+ if (occurrenceService == null) {\r
+ return derivedUnit;\r
+ }\r
+ List<String> propertyPaths = this.config.getPropertyPaths();\r
+ if (propertyPaths == null) {\r
+ return derivedUnit;\r
+ }\r
+ propertyPaths = getDerivedUnitPropertyPaths(propertyPaths);\r
+ DerivedUnit result = (DerivedUnit) occurrenceService.load(\r
+ derivedUnit.getUuid(), propertyPaths);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Initializes the derived unit according to the configuartions property\r
+ * path. If the property path is <code>null</code> or no occurrence service\r
+ * is given the returned object is the same as the input parameter.\r
+ * \r
+ * @param fieldUnit\r
+ * @return\r
+ */\r
+ private FieldUnit getInitializedFieldUnit(FieldUnit fieldUnit) {\r
+ IOccurrenceService occurrenceService = this.config\r
+ .getOccurrenceService();\r
+ if (occurrenceService == null) {\r
+ return fieldUnit;\r
+ }\r
+ List<String> propertyPaths = this.config.getPropertyPaths();\r
+ if (propertyPaths == null) {\r
+ return fieldUnit;\r
+ }\r
+ propertyPaths = getFieldObjectPropertyPaths(propertyPaths);\r
+ FieldUnit result = (FieldUnit) occurrenceService.load(\r
+ fieldUnit.getUuid(), propertyPaths);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Transforms the property paths in a way that the facade is handled just\r
+ * like an ordinary CdmBase object.<BR>\r
+ * E.g. a property path "collectinAreas" will be translated into\r
+ * gatheringEvent.collectingAreas\r
+ * \r
+ * @param propertyPaths\r
+ * @return\r
+ */\r
+ private List<String> getFieldObjectPropertyPaths(List<String> propertyPaths) {\r
+ List<String> result = new ArrayList<String>();\r
+ for (String facadePath : propertyPaths) {\r
+ // collecting areas (named area)\r
+ if (facadePath.startsWith("collectingAreas")) {\r
+ facadePath = "gatheringEvent." + facadePath;\r
+ result.add(facadePath);\r
}\r
+ // collector (agentBase)\r
+ else if (facadePath.startsWith("collector")) {\r
+ facadePath = facadePath.replace("collector",\r
+ "gatheringEvent.actor");\r
+ result.add(facadePath);\r
+ }\r
+ // exactLocation (agentBase)\r
+ else if (facadePath.startsWith("exactLocation")) {\r
+ facadePath = "gatheringEvent." + facadePath;\r
+ result.add(facadePath);\r
+ }\r
+ // gatheringPeriod (TimePeriod)\r
+ else if (facadePath.startsWith("gatheringPeriod")) {\r
+ facadePath = facadePath.replace("gatheringPeriod",\r
+ "gatheringEvent.timeperiod");\r
+ result.add(facadePath);\r
+ }\r
+ // (locality/ localityLanguage , LanguageString)\r
+ else if (facadePath.startsWith("locality")) {\r
+ facadePath = "gatheringEvent." + facadePath;\r
+ result.add(facadePath);\r
+ }\r
+\r
+ // *********** FIELD OBJECT ************\r
+ // fieldObjectDefinitions (Map<language, languageString)\r
+ else if (facadePath.startsWith("fieldObjectDefinitions")) {\r
+ // TODO or definition ???\r
+ facadePath = facadePath.replace("fieldObjectDefinitions",\r
+ "description");\r
+ result.add(facadePath);\r
+ }\r
+ // fieldObjectMedia (Media)\r
+ else if (facadePath.startsWith("fieldObjectMedia")) {\r
+ // TODO ???\r
+ facadePath = facadePath.replace("fieldObjectMedia",\r
+ "descriptions.elements.media");\r
+ result.add(facadePath);\r
+ }\r
+\r
+ // Gathering Event will always be added\r
+ result.add("gatheringEvent");\r
+\r
}\r
- \r
- //handle fieldObservation.getMedia()\r
- if (fieldObservation != null && fieldObservation.getMedia() != null && fieldObservation.getMedia().size() > 0){\r
- //TODO better changed model here to allow only one place for images\r
- if (this.config.isMoveFieldObjectMediaToGallery()){\r
- Set<Media> mediaSet = fieldObservation.getMedia();\r
- for (Media media : mediaSet){\r
- this.addFieldObjectMedia(media);\r
- }\r
- mediaSet.removeAll(getFieldObjectMedia());\r
- }else{\r
- throw new DerivedUnitFacadeNotSupportedException("Field object may not have direct media. Only (one) image gallery is allowed");\r
+\r
+ /*\r
+ * Gathering Event ==================== - gatheringEvent\r
+ * (GatheringEvent)\r
+ * \r
+ * Field Object ================= - ecology/ ecologyAll (String) ??? -\r
+ * plant description (like ecology)\r
+ * \r
+ * - fieldObjectImageGallery (SpecimenDescription) - is automatically\r
+ * initialized via fieldObjectMedia\r
+ */\r
+\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Transforms the property paths in a way that the facade is handled just\r
+ * like an ordinary CdmBase object.<BR>\r
+ * E.g. a property path "collectinAreas" will be translated into\r
+ * gatheringEvent.collectingAreas\r
+ * \r
+ * Not needed (?) as the facade works with REST service property paths\r
+ * without using this method.\r
+ * \r
+ * @param propertyPaths\r
+ * @return\r
+ */\r
+ private List<String> getDerivedUnitPropertyPaths(List<String> propertyPaths) {\r
+ List<String> result = new ArrayList<String>();\r
+ for (String facadePath : propertyPaths) {\r
+ // determinations (DeterminationEvent)\r
+ if (facadePath.startsWith("determinations")) {\r
+ facadePath = "" + facadePath; // no change\r
+ result.add(facadePath);\r
+ }\r
+ // storedUnder (TaxonNameBase)\r
+ else if (facadePath.startsWith("storedUnder")) {\r
+ facadePath = "" + facadePath; // no change\r
+ result.add(facadePath);\r
}\r
+ // sources (IdentifiableSource)\r
+ else if (facadePath.startsWith("sources")) {\r
+ facadePath = "" + facadePath; // no change\r
+ result.add(facadePath);\r
+ }\r
+ // collection (Collection)\r
+ else if (facadePath.startsWith("collection")) {\r
+ facadePath = "" + facadePath; // no change\r
+ result.add(facadePath);\r
+ }\r
+ // (locality/ localityLanguage , LanguageString)\r
+ else if (facadePath.startsWith("locality")) {\r
+ facadePath = "gatheringEvent." + facadePath;\r
+ result.add(facadePath);\r
+ }\r
+\r
+ // *********** FIELD OBJECT ************\r
+ // derivedUnitDefinitions (Map<language, languageString)\r
+ else if (facadePath.startsWith("derivedUnitDefinitions")) {\r
+ // TODO or definition ???\r
+ facadePath = facadePath.replace("derivedUnitDefinitions",\r
+ "description");\r
+ result.add(facadePath);\r
+ }\r
+\r
+ // derivedUnitMedia (Media)\r
+ else if (facadePath.startsWith("derivedUnitMedia")) {\r
+ // TODO ???\r
+ facadePath = facadePath.replace("derivedUnitMedia",\r
+ "descriptions.elements.media");\r
+ result.add(facadePath);\r
+ }\r
+\r
}\r
- \r
- //test if descriptions are supported\r
- ecology = initializeFieldObjectTextDataWithSupportTest(Feature.ECOLOGY(), false, false);\r
- plantDescription = initializeFieldObjectTextDataWithSupportTest(Feature.DESCRIPTION(), false, false);\r
+\r
+ /*\r
+ * //TODO Derived Unit =====================\r
+ * \r
+ * - derivedUnitImageGallery (SpecimenDescription) - is automatically\r
+ * initialized via derivedUnitMedia\r
+ * \r
+ * - derivationEvent (DerivationEvent) - will always be initialized -\r
+ * duplicates (??? Specimen???) ???\r
+ */\r
+\r
+ return result;\r
}\r
- \r
\r
/**\r
* \r
*/\r
private void setCacheStrategy() {\r
- derivedUnit.setCacheStrategy(new DerivedUnitFacadeCacheStrategy());\r
+ if (derivedUnit == null) {\r
+ throw new NullPointerException(\r
+ "Facade's derviedUnit must not be null to set cache strategy");\r
+ }else{\r
+ derivedUnit.setCacheStrategy(new DerivedUnitFacadeCacheStrategy());\r
+ setFieldUnitCacheStrategy();\r
+ }\r
}\r
\r
+ private void setFieldUnitCacheStrategy() {\r
+ if (this.hasFieldObject()){\r
+ DerivedUnitFacadeFieldUnitCacheStrategy strategy = new DerivedUnitFacadeFieldUnitCacheStrategy();\r
+ this.fieldUnit.setCacheStrategy(strategy);\r
+ }\r
+ }\r
\r
/**\r
* @param feature\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private TextData initializeFieldObjectTextDataWithSupportTest(Feature feature, boolean createIfNotExists, boolean isImageGallery) throws DerivedUnitFacadeNotSupportedException {\r
- //field object\r
- FieldObservation fieldObject = getFieldObservation(createIfNotExists) ;\r
- if (fieldObject == null){\r
+ private TextData initializeFieldObjectTextDataWithSupportTest(\r
+ Feature feature, boolean createIfNotExists, boolean isImageGallery)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ // field object\r
+ FieldUnit fieldObject = getFieldUnit(createIfNotExists);\r
+ if (fieldObject == null) {\r
return null;\r
}\r
- return inititialzeTextDataWithSupportTest(feature, fieldObject, createIfNotExists, isImageGallery);\r
+ return inititializeTextDataWithSupportTest(feature, fieldObject,\r
+ createIfNotExists, isImageGallery);\r
}\r
\r
-\r
/**\r
* @param feature\r
* @param specimen\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private TextData inititialzeTextDataWithSupportTest(Feature feature, SpecimenOrObservationBase specimen, boolean createIfNotExists, \r
- boolean isImageGallery) throws DerivedUnitFacadeNotSupportedException {\r
- if (feature == null ){\r
+ private TextData inititializeTextDataWithSupportTest(Feature feature,\r
+ SpecimenOrObservationBase specimen, boolean createIfNotExists,\r
+ boolean isImageGallery)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (feature == null) {\r
return null;\r
}\r
TextData textData = null;\r
- if (createIfNotExists){\r
+ if (createIfNotExists) {\r
textData = TextData.NewInstance(feature);\r
}\r
- \r
+\r
Set<SpecimenDescription> descriptions;\r
- if (isImageGallery){\r
+ if (isImageGallery) {\r
descriptions = specimen.getSpecimenDescriptionImageGallery();\r
- }else{\r
+ } else {\r
descriptions = specimen.getSpecimenDescriptions(false);\r
}\r
- if (descriptions.size() == 0){\r
- if (createIfNotExists){\r
- SpecimenDescription newSpecimenDescription = SpecimenDescription.NewInstance(specimen);\r
+ // no description exists yet for this specimen\r
+ if (descriptions.size() == 0) {\r
+ if (createIfNotExists) {\r
+ SpecimenDescription newSpecimenDescription = SpecimenDescription\r
+ .NewInstance(specimen);\r
newSpecimenDescription.addElement(textData);\r
+ newSpecimenDescription.setImageGallery(isImageGallery);\r
return textData;\r
- }else{\r
+ } else {\r
return null;\r
}\r
}\r
+ // description already exists\r
Set<DescriptionElementBase> existingTextData = new HashSet<DescriptionElementBase>();\r
- for (SpecimenDescription description : descriptions){\r
- for (DescriptionElementBase element: description.getElements()){\r
- if (element.isInstanceOf(TextData.class) && ( feature.equals(element.getFeature() )|| isImageGallery ) ){\r
+ for (SpecimenDescription description : descriptions) {\r
+ // collect all existing text data\r
+ for (DescriptionElementBase element : description.getElements()) {\r
+ if (element.isInstanceOf(TextData.class)\r
+ && (feature.equals(element.getFeature()) || isImageGallery)) {\r
existingTextData.add(element);\r
}\r
}\r
}\r
- if (existingTextData.size() > 1){\r
- throw new DerivedUnitFacadeNotSupportedException("Specimen facade does not support more than one description text data of type " + feature.getLabel());\r
- \r
- }else if (existingTextData.size() == 1){\r
- return CdmBase.deproxy(existingTextData.iterator().next(), TextData.class);\r
- }else{\r
- SpecimenDescription description = descriptions.iterator().next();\r
- description.addElement(textData);\r
+ // use existing text data if exactly one exists\r
+ if (existingTextData.size() > 1) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Specimen facade does not support more than one description text data of type "\r
+ + feature.getLabel());\r
+\r
+ } else if (existingTextData.size() == 1) {\r
+ return CdmBase.deproxy(existingTextData.iterator().next(),\r
+ TextData.class);\r
+ } else {\r
+ if (createIfNotExists) {\r
+ SpecimenDescription description = descriptions.iterator()\r
+ .next();\r
+ description.addElement(textData);\r
+ }\r
return textData;\r
}\r
}\r
\r
-//************************** METHODS ***************************************** \r
+ /**\r
+ * Tests if a given image gallery is supported by the derived unit facade.\r
+ * It returns the only text data attached to the given image gallery. If the\r
+ * given image gallery does not have text data attached, it is created and\r
+ * attached.\r
+ * \r
+ * @param imageGallery\r
+ * @return\r
+ * @throws DerivedUnitFacadeNotSupportedException\r
+ */\r
+ private TextData testImageGallery(SpecimenDescription imageGallery)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (imageGallery.isImageGallery() == false) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Image gallery needs to have image gallery flag set");\r
+ }\r
+ if (imageGallery.getElements().size() > 1) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Image gallery must not have more then one description element");\r
+ }\r
+ TextData textData;\r
+ if (imageGallery.getElements().size() == 0) {\r
+ textData = TextData.NewInstance(Feature.IMAGE());\r
+ imageGallery.addElement(textData);\r
+ } else {\r
+ if (!imageGallery.getElements().iterator().next()\r
+ .isInstanceOf(TextData.class)) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Image gallery must only have TextData as element");\r
+ } else {\r
+ textData = CdmBase.deproxy(imageGallery.getElements()\r
+ .iterator().next(), TextData.class);\r
+ }\r
+ }\r
+ return textData;\r
+ }\r
\r
- private TextData getDerivedUnitImageGalleryTextData(boolean createIfNotExists) throws DerivedUnitFacadeNotSupportedException{\r
- if (this.derivedUnitMediaTextData == null && createIfNotExists){\r
- this.derivedUnitMediaTextData = getImageGalleryTextData(derivedUnit, "Specimen");\r
+ // ************************** METHODS\r
+ // *****************************************\r
+\r
+ private TextData getDerivedUnitImageGalleryTextData(\r
+ boolean createIfNotExists)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (this.derivedUnitMediaTextData == null && createIfNotExists) {\r
+ this.derivedUnitMediaTextData = getImageGalleryTextData(\r
+ derivedUnit, "Specimen");\r
}\r
return this.derivedUnitMediaTextData;\r
}\r
- \r
- private TextData getObservationImageGalleryTextData(boolean createIfNotExists) throws DerivedUnitFacadeNotSupportedException{\r
- if (this.fieldObjectMediaTextData == null && createIfNotExists){\r
- this.fieldObjectMediaTextData = getImageGalleryTextData(fieldObservation, "Field observation");\r
+\r
+ private TextData getObservationImageGalleryTextData(\r
+ boolean createIfNotExists)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (this.fieldObjectMediaTextData == null && createIfNotExists) {\r
+ this.fieldObjectMediaTextData = getImageGalleryTextData(fieldUnit, "Field unit");\r
}\r
return this.fieldObjectMediaTextData;\r
}\r
\r
- \r
- \r
/**\r
- * @param derivationEvent2\r
+ * @param derivationEvent\r
* @return\r
- * @throws DerivedUnitFacadeNotSupportedException \r
+ * @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private Set<FieldObservation> getFieldObservationsOriginals(DerivationEvent derivationEvent, Set<SpecimenOrObservationBase> recursionAvoidSet) throws DerivedUnitFacadeNotSupportedException {\r
- if (recursionAvoidSet == null){\r
+ private Set<FieldUnit> getFieldUnitOriginals(\r
+ DerivationEvent derivationEvent,\r
+ Set<SpecimenOrObservationBase> recursionAvoidSet)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (recursionAvoidSet == null) {\r
recursionAvoidSet = new HashSet<SpecimenOrObservationBase>();\r
}\r
- Set<FieldObservation> result = new HashSet<FieldObservation>();\r
+ Set<FieldUnit> result = new HashSet<FieldUnit>();\r
Set<SpecimenOrObservationBase> originals = derivationEvent.getOriginals();\r
- for (SpecimenOrObservationBase original : originals){\r
- if (original.isInstanceOf(FieldObservation.class)){\r
- result.add(CdmBase.deproxy(original, FieldObservation.class));\r
- }else if (original.isInstanceOf(DerivedUnitBase.class)){\r
- //if specimen has already been tested exclude it from further recursion\r
- if (recursionAvoidSet.contains(original)){\r
+ for (SpecimenOrObservationBase original : originals) {\r
+ if (original.isInstanceOf(FieldUnit.class)) {\r
+ result.add(CdmBase.deproxy(original, FieldUnit.class));\r
+ } else if (original.isInstanceOf(DerivedUnit.class)) {\r
+ // if specimen has already been tested exclude it from further\r
+ // recursion\r
+ if (recursionAvoidSet.contains(original)) {\r
continue;\r
}\r
- DerivedUnitBase derivedUnit = CdmBase.deproxy(original, DerivedUnitBase.class);\r
+ DerivedUnit derivedUnit = CdmBase.deproxy(original,\r
+ DerivedUnit.class);\r
DerivationEvent originalDerivation = derivedUnit.getDerivedFrom();\r
-// Set<DerivationEvent> derivationEvents = original.getDerivationEvents(); \r
-// for (DerivationEvent originalDerivation : derivationEvents){\r
- Set<FieldObservation> fieldObservations = getFieldObservationsOriginals(originalDerivation, recursionAvoidSet);\r
- result.addAll(fieldObservations);\r
-// }\r
- }else{\r
- throw new DerivedUnitFacadeNotSupportedException("Unhandled specimen or observation base type: " + original.getClass().getName() );\r
+ // Set<DerivationEvent> derivationEvents =\r
+ // original.getDerivationEvents();\r
+ // for (DerivationEvent originalDerivation : derivationEvents){\r
+ Set<FieldUnit> fieldUnits = getFieldUnitOriginals(\r
+ originalDerivation, recursionAvoidSet);\r
+ result.addAll(fieldUnits);\r
+ // }\r
+ } else {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Unhandled specimen or observation base type: "\r
+ + original.getClass().getName());\r
}\r
- \r
+\r
}\r
return result;\r
}\r
- \r
- //*********** MEDIA METHODS ******************************\r
- \r
-// /**\r
-// * Returns the media list for a specimen. Throws an exception if the existing specimen descriptions\r
-// * are not supported by this facade.\r
-// * @param specimen the specimen the media belongs to\r
-// * @param specimenExceptionText text describing the specimen for exception messages\r
-// * @return\r
-// * @throws DerivedUnitFacadeNotSupportedException\r
-// */\r
-// private List<Media> getImageGalleryMedia(SpecimenOrObservationBase specimen, String specimenExceptionText) throws DerivedUnitFacadeNotSupportedException{\r
-// List<Media> result;\r
-// SpecimenDescription imageGallery = getImageGalleryWithSupportTest(specimen, specimenExceptionText, true);\r
-// TextData textData = getImageTextDataWithSupportTest(imageGallery, specimenExceptionText);\r
-// result = textData.getMedia();\r
-// return result;\r
-// }\r
- \r
+\r
+ // *********** MEDIA METHODS ******************************\r
+\r
+ // /**\r
+ // * Returns the media list for a specimen. Throws an exception if the\r
+ // existing specimen descriptions\r
+ // * are not supported by this facade.\r
+ // * @param specimen the specimen the media belongs to\r
+ // * @param specimenExceptionText text describing the specimen for exception\r
+ // messages\r
+ // * @return\r
+ // * @throws DerivedUnitFacadeNotSupportedException\r
+ // */\r
+ // private List<Media> getImageGalleryMedia(SpecimenOrObservationBase\r
+ // specimen, String specimenExceptionText) throws\r
+ // DerivedUnitFacadeNotSupportedException{\r
+ // List<Media> result;\r
+ // SpecimenDescription imageGallery =\r
+ // getImageGalleryWithSupportTest(specimen, specimenExceptionText, true);\r
+ // TextData textData = getImageTextDataWithSupportTest(imageGallery,\r
+ // specimenExceptionText);\r
+ // result = textData.getMedia();\r
+ // return result;\r
+ // }\r
+\r
/**\r
- * Returns the media list for a specimen. Throws an exception if the existing specimen descriptions\r
- * are not supported by this facade.\r
- * @param specimen the specimen the media belongs to\r
- * @param specimenExceptionText text describing the specimen for exception messages\r
+ * Returns the media list for a specimen. Throws an exception if the\r
+ * existing specimen descriptions are not supported by this facade.\r
+ * \r
+ * @param specimen\r
+ * the specimen the media belongs to\r
+ * @param specimenExceptionText\r
+ * text describing the specimen for exception messages\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private TextData getImageGalleryTextData(SpecimenOrObservationBase specimen, String specimenExceptionText) throws DerivedUnitFacadeNotSupportedException{\r
+ private TextData getImageGalleryTextData(SpecimenOrObservationBase specimen, String specimenExceptionText)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
TextData result;\r
- SpecimenDescription imageGallery = getImageGalleryWithSupportTest(specimen, specimenExceptionText, true);\r
- result = getImageTextDataWithSupportTest(imageGallery, specimenExceptionText);\r
+ SpecimenDescription imageGallery = getImageGalleryWithSupportTest(\r
+ specimen, specimenExceptionText, true);\r
+ result = getImageTextDataWithSupportTest(imageGallery,\r
+ specimenExceptionText);\r
return result;\r
}\r
- \r
- \r
+\r
/**\r
- * Returns the image gallery of the according specimen. Throws an exception if the attached\r
- * image gallerie(s) are not supported by this facade.\r
- * If no image gallery exists a new one is created if <code>createNewIfNotExists</code> is true and\r
- * if specimen is not <code>null</code>.\r
+ * Returns the image gallery of the according specimen. Throws an exception\r
+ * if the attached image gallerie(s) are not supported by this facade. If no\r
+ * image gallery exists a new one is created if\r
+ * <code>createNewIfNotExists</code> is true and if specimen is not\r
+ * <code>null</code>.\r
+ * \r
* @param specimen\r
* @param specimenText\r
* @param createNewIfNotExists\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private SpecimenDescription getImageGalleryWithSupportTest(SpecimenOrObservationBase<?> specimen, String specimenText, boolean createNewIfNotExists) throws DerivedUnitFacadeNotSupportedException{\r
- if (specimen == null){\r
+ private SpecimenDescription getImageGalleryWithSupportTest(\r
+ SpecimenOrObservationBase<?> specimen, String specimenText,\r
+ boolean createNewIfNotExists)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (specimen == null) {\r
return null;\r
}\r
SpecimenDescription imageGallery;\r
- if (hasMultipleImageGalleries(specimen)){\r
- throw new DerivedUnitFacadeNotSupportedException( specimenText + " must not have more than 1 image gallery");\r
- }else{\r
+ if (hasMultipleImageGalleries(specimen)) {\r
+ throw new DerivedUnitFacadeNotSupportedException(specimenText\r
+ + " must not have more than 1 image gallery");\r
+ } else {\r
imageGallery = getImageGallery(specimen, createNewIfNotExists);\r
getImageTextDataWithSupportTest(imageGallery, specimenText);\r
}\r
return imageGallery;\r
}\r
- \r
+\r
/**\r
- * Returns the media holding text data element of the image gallery. Throws an exception if multiple\r
- * such text data already exist.\r
- * Creates a new text data if none exists and adds it to the image gallery.\r
- * If image gallery is <code>null</code> nothing happens.\r
+ * Returns the media holding text data element of the image gallery. Throws\r
+ * an exception if multiple such text data already exist. Creates a new text\r
+ * data if none exists and adds it to the image gallery. If image gallery is\r
+ * <code>null</code> nothing happens.\r
+ * \r
* @param imageGallery\r
* @param textData\r
* @return\r
- * @throws DerivedUnitFacadeNotSupportedException \r
+ * @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private TextData getImageTextDataWithSupportTest(SpecimenDescription imageGallery, String specimenText) throws DerivedUnitFacadeNotSupportedException {\r
- if (imageGallery == null){\r
+ private TextData getImageTextDataWithSupportTest(\r
+ SpecimenDescription imageGallery, String specimenText)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (imageGallery == null) {\r
return null;\r
}\r
TextData textData = null;\r
- for (DescriptionElementBase element: imageGallery.getElements()){\r
- if (element.isInstanceOf(TextData.class) && element.getFeature().equals(Feature.IMAGE())){\r
- if (textData != null){\r
- throw new DerivedUnitFacadeNotSupportedException( specimenText + " must not have more than 1 image text data element in image gallery");\r
+ for (DescriptionElementBase element : imageGallery.getElements()) {\r
+ if (element.isInstanceOf(TextData.class)\r
+ && element.getFeature().equals(Feature.IMAGE())) {\r
+ if (textData != null) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ specimenText\r
+ + " must not have more than 1 image text data element in image gallery");\r
}\r
textData = CdmBase.deproxy(element, TextData.class);\r
}\r
}\r
- if (textData == null){\r
+ if (textData == null) {\r
textData = TextData.NewInstance(Feature.IMAGE());\r
imageGallery.addElement(textData);\r
}\r
}\r
\r
/**\r
- * Checks, if a specimen belongs to more than one description that is an image gallery\r
+ * Checks, if a specimen belongs to more than one description that is an\r
+ * image gallery\r
+ * \r
* @param derivedUnit\r
* @return\r
*/\r
- private boolean hasMultipleImageGalleries(SpecimenOrObservationBase<?> derivedUnit){\r
+ private boolean hasMultipleImageGalleries(\r
+ SpecimenOrObservationBase<?> derivedUnit) {\r
int count = 0;\r
- Set<SpecimenDescription> descriptions= derivedUnit.getSpecimenDescriptions();\r
- for (SpecimenDescription description : descriptions){\r
- if (description.isImageGallery()){\r
+ Set<SpecimenDescription> descriptions = derivedUnit\r
+ .getSpecimenDescriptions();\r
+ for (SpecimenDescription description : descriptions) {\r
+ if (description.isImageGallery()) {\r
count++;\r
}\r
}\r
return (count > 1);\r
}\r
\r
- \r
/**\r
- * Returns the image gallery for a specimen. If there are multiple specimen descriptions\r
- * marked as image galleries an arbitrary one is chosen.\r
- * If no image gallery exists, a new one is created if <code>createNewIfNotExists</code>\r
- * is <code>true</code>.<Br>\r
+ * Returns the image gallery for a specimen. If there are multiple specimen\r
+ * descriptions marked as image galleries an arbitrary one is chosen. If no\r
+ * image gallery exists, a new one is created if\r
+ * <code>createNewIfNotExists</code> is <code>true</code>.<Br>\r
* If specimen is <code>null</code> a null pointer exception is thrown.\r
+ * \r
* @param createNewIfNotExists\r
* @return\r
*/\r
private SpecimenDescription getImageGallery(SpecimenOrObservationBase<?> specimen, boolean createIfNotExists) {\r
SpecimenDescription result = null;\r
- Set<SpecimenDescription> descriptions= specimen.getSpecimenDescriptions();\r
- for (SpecimenDescription description : descriptions){\r
- if (description.isImageGallery()){\r
+ Set<SpecimenDescription> descriptions = specimen.getSpecimenDescriptions();\r
+ for (SpecimenDescription description : descriptions) {\r
+ if (description.isImageGallery()) {\r
result = description;\r
break;\r
}\r
}\r
- if (result == null && createIfNotExists){\r
+ if (result == null && createIfNotExists) {\r
result = SpecimenDescription.NewInstance(specimen);\r
result.setImageGallery(true);\r
}\r
return result;\r
}\r
- \r
+\r
/**\r
- * Adds a media to the specimens image gallery. If media is <code>null</code> nothing happens.\r
+ * Adds a media to the specimens image gallery. If media is\r
+ * <code>null</code> nothing happens.\r
+ * \r
* @param media\r
* @param specimen\r
- * @return true if media is not null (as specified by {@link java.util.Collection#add(Object) Collection.add(E e)} \r
+ * @return true if media is not null (as specified by\r
+ * {@link java.util.Collection#add(Object) Collection.add(E e)}\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
private boolean addMedia(Media media, SpecimenOrObservationBase<?> specimen) throws DerivedUnitFacadeNotSupportedException {\r
- if (media != null){\r
- List<Media> mediaList = getMedia(specimen, true);\r
- return mediaList.add(media);\r
- }else{\r
+ if (media != null) {\r
+ List<Media> mediaList = getMediaList(specimen, true);\r
+ if (! mediaList.contains(media)){\r
+ return mediaList.add(media);\r
+ }else{\r
+ return true;\r
+ }\r
+ } else {\r
return false;\r
}\r
}\r
\r
/**\r
* Removes a media from the specimens image gallery.\r
+ * \r
* @param media\r
* @param specimen\r
- * @return true if an element was removed as a result of this call (as specified by {@link java.util.Collection#remove(Object) Collection.remove(E e)} \r
+ * @return true if an element was removed as a result of this call (as\r
+ * specified by {@link java.util.Collection#remove(Object)\r
+ * Collection.remove(E e)}\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private boolean removeMedia(Media media, SpecimenOrObservationBase<?> specimen) throws DerivedUnitFacadeNotSupportedException {\r
- List<Media> mediaList = getMedia(specimen, true);\r
+ private boolean removeMedia(Media media,\r
+ SpecimenOrObservationBase<?> specimen)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ List<Media> mediaList = getMediaList(specimen, true);\r
return mediaList == null ? null : mediaList.remove(media);\r
}\r
\r
- private List<Media> getMedia(SpecimenOrObservationBase<?> specimen, boolean createIfNotExists) throws DerivedUnitFacadeNotSupportedException {\r
+ private List<Media> getMediaList(SpecimenOrObservationBase<?> specimen, boolean createIfNotExists)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
TextData textData = getMediaTextData(specimen, createIfNotExists);\r
return textData == null ? null : textData.getMedia();\r
}\r
- \r
+\r
/**\r
- * Returns the one media list of a specimen which is part of the only image gallery that \r
- * this specimen is part of.<BR>\r
+ * Returns the one media list of a specimen which is part of the only image\r
+ * gallery that this specimen is part of.<BR>\r
* If these conditions are not hold an exception is thrwon.\r
+ * \r
* @param specimen\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
-// private List<Media> getMedia(SpecimenOrObservationBase<?> specimen) throws DerivedUnitFacadeNotSupportedException {\r
-// if (specimen == null){\r
-// return null;\r
-// }\r
-// if (specimen == this.derivedUnit){\r
-// return getDerivedUnitImageGalleryMedia();\r
-// }else if (specimen == this.fieldObservation){\r
-// return getObservationImageGalleryTextData();\r
-// }else{\r
-// return getImageGalleryMedia(specimen, "Undefined specimen ");\r
-// }\r
-// }\r
- \r
+ // private List<Media> getMedia(SpecimenOrObservationBase<?> specimen)\r
+ // throws DerivedUnitFacadeNotSupportedException {\r
+ // if (specimen == null){\r
+ // return null;\r
+ // }\r
+ // if (specimen == this.derivedUnit){\r
+ // return getDerivedUnitImageGalleryMedia();\r
+ // }else if (specimen == this.fieldUnit){\r
+ // return getObservationImageGalleryTextData();\r
+ // }else{\r
+ // return getImageGalleryMedia(specimen, "Undefined specimen ");\r
+ // }\r
+ // }\r
+\r
/**\r
- * Returns the one media list of a specimen which is part of the only image gallery that \r
- * this specimen is part of.<BR>\r
+ * Returns the one media list of a specimen which is part of the only image\r
+ * gallery that this specimen is part of.<BR>\r
* If these conditions are not hold an exception is thrwon.\r
+ * \r
* @param specimen\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private TextData getMediaTextData(SpecimenOrObservationBase<?> specimen, boolean createIfNotExists) throws DerivedUnitFacadeNotSupportedException {\r
- if (specimen == null){\r
+ private TextData getMediaTextData(SpecimenOrObservationBase<?> specimen,\r
+ boolean createIfNotExists)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ if (specimen == null) {\r
return null;\r
}\r
- if (specimen == this.derivedUnit){\r
+ if (specimen == this.derivedUnit) {\r
return getDerivedUnitImageGalleryTextData(createIfNotExists);\r
- }else if (specimen == this.fieldObservation){\r
+ } else if (specimen == this.fieldUnit) {\r
return getObservationImageGalleryTextData(createIfNotExists);\r
- }else{\r
+ } else {\r
return getImageGalleryTextData(specimen, "Undefined specimen ");\r
}\r
}\r
- \r
- \r
-//****************** GETTER / SETTER / ADDER / REMOVER ***********************/ \r
- \r
-// ****************** Gathering Event *********************************/\r
- \r
- //Collecting area\r
+\r
+ // ****************** GETTER / SETTER / ADDER / REMOVER\r
+ // ***********************/\r
+\r
+ // ****************** Gathering Event *********************************/\r
+\r
+ // country\r
+ @Transient\r
+ public NamedArea getCountry() {\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getCountry()\r
+ : null);\r
+ }\r
+\r
+ public void setCountry(NamedArea country) {\r
+ getGatheringEvent(true).setCountry(country);\r
+ }\r
+\r
+ // Collecting area\r
public void addCollectingArea(NamedArea area) {\r
getGatheringEvent(true).addCollectingArea(area);\r
}\r
+\r
public void addCollectingAreas(java.util.Collection<NamedArea> areas) {\r
- for (NamedArea area : areas){\r
+ for (NamedArea area : areas) {\r
getGatheringEvent(true).addCollectingArea(area);\r
}\r
}\r
+\r
+ @Transient\r
public Set<NamedArea> getCollectingAreas() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getCollectingAreas() : null);\r
+ return (hasGatheringEvent() ? getGatheringEvent(true)\r
+ .getCollectingAreas() : null);\r
}\r
+\r
public void removeCollectingArea(NamedArea area) {\r
- if (hasGatheringEvent()){\r
+ if (hasGatheringEvent()) {\r
getGatheringEvent(true).removeCollectingArea(area);\r
}\r
}\r
\r
- //absolute elevation \r
- /** meter above/below sea level of the surface \r
+ /**\r
+ * Returns the correctly formatted <code>absolute elevation</code> information.\r
+ * If absoluteElevationText is set, this will be returned,\r
+ * otherwise we absoluteElevation will be returned, followed by absoluteElevationMax \r
+ * if existing, separated by " - " \r
+ * @return\r
+ */\r
+ @Transient\r
+ public String absoluteElevationToString() {\r
+ if (! hasGatheringEvent()){\r
+ return null;\r
+ }else{\r
+ GatheringEvent ev = getGatheringEvent(true);\r
+ if (StringUtils.isNotBlank(ev.getAbsoluteElevationText())){\r
+ return ev.getAbsoluteElevationText();\r
+ }else{\r
+ String text = ev.getAbsoluteElevationText();\r
+ Integer min = getAbsoluteElevation();\r
+ Integer max = getAbsoluteElevationMaximum();\r
+ return distanceString(min, max, text);\r
+ }\r
+ }\r
+ }\r
+\r
+ \r
+ /**\r
+ * meter above/below sea level of the surface\r
+ * \r
* @see #getAbsoluteElevationError()\r
* @see #getAbsoluteElevationRange()\r
**/\r
+ @Transient\r
public Integer getAbsoluteElevation() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getAbsoluteElevation() : null);\r
}\r
+\r
public void setAbsoluteElevation(Integer absoluteElevation) {\r
getGatheringEvent(true).setAbsoluteElevation(absoluteElevation);\r
}\r
\r
- //absolute elevation error\r
- public Integer getAbsoluteElevationError() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getAbsoluteElevationError() : null);\r
+ public void setAbsoluteElevationMax(Integer absoluteElevationMax) {\r
+ getGatheringEvent(true).setAbsoluteElevationMax(absoluteElevationMax);\r
}\r
- public void setAbsoluteElevationError(Integer absoluteElevationError) {\r
- getGatheringEvent(true).setAbsoluteElevationError(absoluteElevationError);\r
+ \r
+ public void setAbsoluteElevationText(String absoluteElevationText) {\r
+ getGatheringEvent(true).setAbsoluteElevationText(absoluteElevationText);\r
}\r
\r
/**\r
* @see #getAbsoluteElevation()\r
* @see #getAbsoluteElevationError()\r
* @see #setAbsoluteElevationRange(Integer, Integer)\r
- * @see #getAbsoluteElevationMaximum()\r
+ * @see #getAbsoluteElevationMinimum()\r
*/\r
- public Integer getAbsoluteElevationMinimum(){\r
- if ( ! hasGatheringEvent() ){\r
+ @Transient\r
+ public Integer getAbsoluteElevationMaximum() {\r
+ if (!hasGatheringEvent()) {\r
return null;\r
+ }else{\r
+ return getGatheringEvent(true).getAbsoluteElevationMax();\r
}\r
- Integer minimum = getGatheringEvent(true).getAbsoluteElevation();\r
- if (getGatheringEvent(true).getAbsoluteElevationError() != null){\r
- minimum = minimum - getGatheringEvent(true).getAbsoluteElevationError();\r
- }\r
- return minimum;\r
}\r
+ \r
/**\r
* @see #getAbsoluteElevation()\r
* @see #getAbsoluteElevationError()\r
* @see #setAbsoluteElevationRange(Integer, Integer)\r
* @see #getAbsoluteElevationMinimum()\r
*/\r
- public Integer getAbsoluteElevationMaximum(){\r
- if ( ! hasGatheringEvent() ){\r
+ @Transient\r
+ public String getAbsoluteElevationText() {\r
+ if (!hasGatheringEvent()) {\r
return null;\r
+ }else{\r
+ return getGatheringEvent(true).getAbsoluteElevationText();\r
}\r
- Integer maximum = getGatheringEvent(true).getAbsoluteElevation();\r
- if (getGatheringEvent(true).getAbsoluteElevationError() != null){\r
- maximum = maximum + getGatheringEvent(true).getAbsoluteElevationError();\r
- }\r
- return maximum;\r
}\r
\r
- \r
/**\r
- * This method replaces absoluteElevation and absoulteElevationError by\r
- * internally translating minimum and maximum values into\r
- * average and error values. As all these values are integer based\r
- * it is necessary that the distance is between minimum and maximum is <b>even</b>,\r
- * otherwise we will get a rounding error resulting in a maximum that is increased\r
- * by 1.\r
+ * Convenience method to set absolute elevation minimum and maximum.\r
+ * \r
* @see #setAbsoluteElevation(Integer)\r
- * @see #setAbsoluteElevationError(Integer)\r
+ * @see #setAbsoluteElevationMax(Integer)\r
* @param minimumElevation minimum of the range\r
* @param maximumElevation maximum of the range\r
*/\r
- public void setAbsoluteElevationRange(Integer minimumElevation, Integer maximumElevation){\r
- if (minimumElevation == null || maximumElevation == null){\r
- Integer elevation = minimumElevation;\r
- Integer error = 0;\r
- if (minimumElevation == null){\r
- elevation = maximumElevation;\r
- if (elevation == null){\r
- error = null;\r
- }\r
- }\r
- getGatheringEvent(true).setAbsoluteElevation(elevation);\r
- getGatheringEvent(true).setAbsoluteElevationError(error);\r
- }else{\r
- if (! isEvenDistance(minimumElevation, maximumElevation) ){\r
- throw new IllegalArgumentException("Distance between minimum and maximum elevation must be even but was " + Math.abs(minimumElevation - maximumElevation));\r
- }\r
- Integer absoluteElevationError = Math.abs(maximumElevation - minimumElevation);\r
- absoluteElevationError = absoluteElevationError / 2;\r
- Integer absoluteElevation = minimumElevation + absoluteElevationError;\r
- getGatheringEvent(true).setAbsoluteElevation(absoluteElevation);\r
- getGatheringEvent(true).setAbsoluteElevationError(absoluteElevationError);\r
- }\r
- }\r
-\r
- /**\r
- * @param minimumElevation\r
- * @param maximumElevation\r
- * @return\r
- */\r
- private boolean isEvenDistance(Integer minimumElevation, Integer maximumElevation) {\r
- Integer diff = ( maximumElevation - minimumElevation);\r
- Integer testDiff = (diff /2) *2 ;\r
- return (testDiff == diff);\r
+ public void setAbsoluteElevationRange(Integer minimumElevation, Integer maximumElevation) {\r
+ getGatheringEvent(true).setAbsoluteElevation(minimumElevation);\r
+ getGatheringEvent(true).setAbsoluteElevationMax(maximumElevation);\r
}\r
\r
- //collector\r
+ // collector\r
+ @Transient\r
public AgentBase getCollector() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getCollector() : null);\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getCollector()\r
+ : null);\r
}\r
- public void setCollector(AgentBase collector){\r
+\r
+ public void setCollector(AgentBase collector) {\r
getGatheringEvent(true).setCollector(collector);\r
}\r
\r
- //collecting method\r
+ // collecting method\r
+ @Transient\r
public String getCollectingMethod() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getCollectingMethod() : null);\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getCollectingMethod() : null);\r
}\r
+\r
public void setCollectingMethod(String collectingMethod) {\r
getGatheringEvent(true).setCollectingMethod(collectingMethod);\r
}\r
\r
- //distance to ground\r
- public Integer getDistanceToGround() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getDistanceToGround() : null);\r
+ // distance to ground\r
+ \r
+ /**\r
+ * Returns the correctly formatted <code>distance to ground</code> information.\r
+ * If distanceToGroundText is not blank, it will be returned,\r
+ * otherwise distanceToGround will be returned, followed by distanceToGroundMax \r
+ * if existing, separated by " - " \r
+ * @return\r
+ */\r
+ @Transient\r
+ public String distanceToGroundToString() {\r
+ if (! hasGatheringEvent()){\r
+ return null;\r
+ }else{\r
+ GatheringEvent ev = getGatheringEvent(true);\r
+ String text = ev.getDistanceToGroundText();\r
+ Double min = getDistanceToGround();\r
+ Double max = getDistanceToGroundMax();\r
+ return distanceString(min, max, text);\r
+ }\r
}\r
- public void setDistanceToGround(Integer distanceToGround) {\r
- getGatheringEvent(true).setDistanceToGround(distanceToGround);\r
+\r
+ @Transient\r
+ public Double getDistanceToGround() {\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getDistanceToGround() : null);\r
}\r
\r
- //distance to water surface\r
- public Integer getDistanceToWaterSurface() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getDistanceToWaterSurface() : null);\r
+ public void setDistanceToGround(Double distanceToGround) {\r
+ getGatheringEvent(true).setDistanceToGround(distanceToGround);\r
}\r
- public void setDistanceToWaterSurface(Integer distanceToWaterSurface) {\r
+ \r
+ /**\r
+ * @see #getDistanceToGround()\r
+ * @see #getDistanceToGroundRange(Integer, Integer)\r
+ */\r
+ @Transient\r
+ public Double getDistanceToGroundMax() {\r
+ if (!hasGatheringEvent()) {\r
+ return null;\r
+ }else{\r
+ return getGatheringEvent(true).getDistanceToGroundMax();\r
+ }\r
+ }\r
+ \r
+ public void setDistanceToGroundMax(Double distanceToGroundMax) {\r
+ getGatheringEvent(true).setDistanceToGroundMax(distanceToGroundMax);\r
+ }\r
+ \r
+ /**\r
+ * @see #getDistanceToGround()\r
+ * @see #setDistanceToGroundRange(Integer, Integer)\r
+ */\r
+ @Transient\r
+ public String getDistanceToGroundText() {\r
+ if (!hasGatheringEvent()) {\r
+ return null;\r
+ }else{\r
+ return getGatheringEvent(true).getDistanceToGroundText();\r
+ }\r
+ }\r
+ public void setDistanceToGroundText(String distanceToGroundText) {\r
+ getGatheringEvent(true).setDistanceToGroundText(distanceToGroundText);\r
+ }\r
+ \r
+ /**\r
+ * Convenience method to set distance to ground minimum and maximum.\r
+ * \r
+ * @see #getDistanceToGround()\r
+ * @see #getDistanceToGroundMax()\r
+ * @param minimumDistance minimum of the range\r
+ * @param maximumDistance maximum of the range\r
+ */\r
+ public void setDistanceToGroundRange(Double minimumDistance, Double maximumDistance) throws IllegalArgumentException{\r
+ getGatheringEvent(true).setDistanceToGround(minimumDistance);\r
+ getGatheringEvent(true).setDistanceToGroundMax(maximumDistance);\r
+ }\r
+ \r
+ \r
+ /**\r
+ * Returns the correctly formatted <code>distance to water surface</code> information.\r
+ * If distanceToWaterSurfaceText is not blank, it will be returned,\r
+ * otherwise distanceToWaterSurface will be returned, followed by distanceToWatersurfaceMax \r
+ * if existing, separated by " - " \r
+ * @return\r
+ */\r
+ @Transient\r
+ public String distanceToWaterSurfaceToString() {\r
+ if (! hasGatheringEvent()){\r
+ return null;\r
+ }else{\r
+ GatheringEvent ev = getGatheringEvent(true);\r
+ String text = ev.getDistanceToWaterSurfaceText();\r
+ Double min = getDistanceToWaterSurface();\r
+ Double max = getDistanceToWaterSurfaceMax();\r
+ return distanceString(min, max, text);\r
+ }\r
+ }\r
+ \r
+ // distance to water surface\r
+ @Transient\r
+ public Double getDistanceToWaterSurface() {\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getDistanceToWaterSurface() : null);\r
+ }\r
+\r
+ public void setDistanceToWaterSurface(Double distanceToWaterSurface) {\r
getGatheringEvent(true).setDistanceToWaterSurface(distanceToWaterSurface);\r
}\r
\r
- //exact location\r
- public Point getExactLocation() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getExactLocation() : null );\r
+ /**\r
+ * @see #getDistanceToWaterSurface()\r
+ * @see #getDistanceToWaterSurfaceRange(Double, Double)\r
+ */\r
+ @Transient\r
+ public Double getDistanceToWaterSurfaceMax() {\r
+ if (!hasGatheringEvent()) {\r
+ return null;\r
+ }else{\r
+ return getGatheringEvent(true).getDistanceToWaterSurfaceMax();\r
+ }\r
+ }\r
+ \r
+ public void setDistanceToWaterSurfaceMax(Double distanceToWaterSurfaceMax) {\r
+ getGatheringEvent(true).setDistanceToWaterSurfaceMax(distanceToWaterSurfaceMax);\r
+ }\r
+ \r
+ /**\r
+ * @see #getDistanceToWaterSurface()\r
+ * @see #getDistanceToWaterSurfaceRange(Double, Double)\r
+ */\r
+ @Transient\r
+ public String getDistanceToWaterSurfaceText() {\r
+ if (!hasGatheringEvent()) {\r
+ return null;\r
+ }else{\r
+ return getGatheringEvent(true).getDistanceToWaterSurfaceText();\r
+ }\r
+ }\r
+ public void setDistanceToWaterSurfaceText(String distanceToWaterSurfaceText) {\r
+ getGatheringEvent(true).setDistanceToWaterSurfaceText(distanceToWaterSurfaceText);\r
+ }\r
+ \r
+ /**\r
+ * Convenience method to set distance to ground minimum and maximum.\r
+ * \r
+ * @see #getDistanceToWaterSurface()\r
+ * @see #getDistanceToWaterSurfaceMax()\r
+ * @param minimumDistance minimum of the range, this is the distance which is closer to the water surface\r
+ * @param maximumDistance maximum of the range, this is the distance which is farer to the water surface\r
+ */\r
+ public void setDistanceToWaterSurfaceRange(Double minimumDistance, Double maximumDistance) throws IllegalArgumentException{\r
+ getGatheringEvent(true).setDistanceToWaterSurface(minimumDistance);\r
+ getGatheringEvent(true).setDistanceToWaterSurfaceMax(maximumDistance);\r
}\r
\r
+ \r
+ // exact location\r
+ @Transient\r
+ public Point getExactLocation() {\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getExactLocation() : null);\r
+ }\r
+\r
/**\r
- * Returns a sexagesimal representation of the exact location (e.g. 12°59'N, 35°23E).\r
- * If the exact location is <code>null</code> the empty string is returned.\r
+ * Returns a sexagesimal representation of the exact location (e.g.\r
+ * 12°59'N, 35°23E). If the exact location is <code>null</code> the empty\r
+ * string is returned.\r
+ * \r
* @param includeEmptySeconds\r
* @param includeReferenceSystem\r
* @return\r
*/\r
- public String getExactLocationText(boolean includeEmptySeconds, boolean includeReferenceSystem){\r
- return (this.getExactLocation() == null ? "" : this.getExactLocation().toSexagesimalString(includeEmptySeconds, includeReferenceSystem));\r
+ public String getExactLocationText(boolean includeEmptySeconds,\r
+ boolean includeReferenceSystem) {\r
+ return (this.getExactLocation() == null ? "" : this.getExactLocation()\r
+ .toSexagesimalString(includeEmptySeconds,\r
+ includeReferenceSystem));\r
}\r
+\r
public void setExactLocation(Point exactLocation) {\r
getGatheringEvent(true).setExactLocation(exactLocation);\r
}\r
- public void setExactLocationByParsing(String longitudeToParse, String latitudeToParse, ReferenceSystem referenceSystem, Integer errorRadius) throws ParseException{\r
- Point point = Point.NewInstance(null, null, referenceSystem, errorRadius);\r
+\r
+ public void setExactLocationByParsing(String longitudeToParse,\r
+ String latitudeToParse, ReferenceSystem referenceSystem,\r
+ Integer errorRadius) throws ParseException {\r
+ Point point = Point.NewInstance(null, null, referenceSystem,\r
+ errorRadius);\r
point.setLongitudeByParsing(longitudeToParse);\r
point.setLatitudeByParsing(latitudeToParse);\r
setExactLocation(point);\r
}\r
- \r
- //gathering event description\r
+\r
+ // gathering event description\r
+ @Transient\r
public String getGatheringEventDescription() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getDescription() : null);\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getDescription()\r
+ : null);\r
}\r
+\r
public void setGatheringEventDescription(String description) {\r
getGatheringEvent(true).setDescription(description);\r
}\r
\r
- //gatering period\r
+ // gatering period\r
+ @Transient\r
public TimePeriod getGatheringPeriod() {\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getTimeperiod() : null);\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getTimeperiod()\r
+ : null);\r
}\r
+\r
public void setGatheringPeriod(TimePeriod timeperiod) {\r
getGatheringEvent(true).setTimeperiod(timeperiod);\r
}\r
\r
- //locality\r
- public LanguageString getLocality(){\r
- return (hasGatheringEvent() ? getGatheringEvent(true).getLocality() : null);\r
+ // locality\r
+ @Transient\r
+ public LanguageString getLocality() {\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getLocality()\r
+ : null);\r
}\r
- public String getLocalityText(){\r
+\r
+ /**\r
+ * convienience method for {@link #getLocality()}.\r
+ * {@link LanguageString#getText() getText()}\r
+ * \r
+ * @return\r
+ */\r
+ @Transient\r
+ public String getLocalityText() {\r
LanguageString locality = getLocality();\r
- if(locality != null){\r
+ if (locality != null) {\r
return locality.getText();\r
}\r
return null;\r
}\r
- public Language getLocalityLanguage(){\r
+\r
+ /**\r
+ * convienience method for {@link #getLocality()}.\r
+ * {@link LanguageString#getLanguage() getLanguage()}\r
+ * \r
+ * @return\r
+ */\r
+ @Transient\r
+ public Language getLocalityLanguage() {\r
LanguageString locality = getLocality();\r
- if(locality != null){\r
+ if (locality != null) {\r
return locality.getLanguage();\r
}\r
return null;\r
}\r
- \r
+\r
/**\r
* Sets the locality string in the default language\r
+ * \r
* @param locality\r
*/\r
- public void setLocality(String locality){\r
+ public void setLocality(String locality) {\r
Language language = Language.DEFAULT();\r
setLocality(locality, language);\r
}\r
- public void setLocality(String locality, Language language){\r
+\r
+ public void setLocality(String locality, Language language) {\r
LanguageString langString = LanguageString.NewInstance(locality, language);\r
setLocality(langString);\r
}\r
- public void setLocality(LanguageString locality){\r
+\r
+ public void setLocality(LanguageString locality) {\r
getGatheringEvent(true).setLocality(locality);\r
}\r
- \r
+\r
/**\r
- * The gathering event will be used for the field object instead of the old gathering event.<BR>\r
+ * The gathering event will be used for the field object instead of the old\r
+ * gathering event.<BR>\r
* <B>This method will override all gathering values (see below).</B>\r
+ * \r
* @see #getAbsoluteElevation()\r
* @see #getAbsoluteElevationError()\r
* @see #getDistanceToGround()\r
* @see #getCollectingAreas()\r
* @see #getCollectingMethod()\r
* @see #getLocality()\r
- * @see #getCollector() \r
+ * @see #getCollector()\r
* @param gatheringEvent\r
*/\r
public void setGatheringEvent(GatheringEvent gatheringEvent) {\r
- getFieldObservation(true).setGatheringEvent(gatheringEvent);\r
+ getFieldUnit(true).setGatheringEvent(gatheringEvent);\r
}\r
- public boolean hasGatheringEvent(){\r
+\r
+ public boolean hasGatheringEvent() {\r
return (getGatheringEvent(false) != null);\r
}\r
- public GatheringEvent getGatheringEvent() {\r
+\r
+ public GatheringEvent innerGatheringEvent() {\r
return getGatheringEvent(false);\r
}\r
- \r
+\r
public GatheringEvent getGatheringEvent(boolean createIfNotExists) {\r
- if (! hasFieldObservation() && ! createIfNotExists){\r
+ if (!hasFieldUnit() && !createIfNotExists) {\r
return null;\r
}\r
- if (createIfNotExists && getFieldObservation(true).getGatheringEvent() == null ){\r
+ if (createIfNotExists && getFieldUnit(true).getGatheringEvent() == null) {\r
GatheringEvent gatheringEvent = GatheringEvent.NewInstance();\r
- getFieldObservation(true).setGatheringEvent(gatheringEvent);\r
+ getFieldUnit(true).setGatheringEvent(gatheringEvent);\r
}\r
- return getFieldObservation(true).getGatheringEvent();\r
+ return getFieldUnit(true).getGatheringEvent();\r
}\r
- \r
-// ****************** Field Object ************************************/\r
- \r
+\r
+ // ****************** Field Object ************************************/\r
+\r
/**\r
- * Returns true if a field observation exists (even if all attributes are empty or <code>null<code>.\r
+ * Returns true if a field unit exists (even if all attributes are\r
+ * empty or <code>null<code>.\r
+ * \r
* @return\r
*/\r
- public boolean hasFieldObject(){\r
- return this.fieldObservation != null;\r
+ public boolean hasFieldObject() {\r
+ return this.fieldUnit != null;\r
}\r
- \r
- //ecology\r
- public String getEcology(){\r
+\r
+ // ecology\r
+ @Transient\r
+ public String getEcology() {\r
return getEcology(Language.DEFAULT());\r
}\r
- public String getEcology(Language language){\r
+\r
+ public String getEcology(Language language) {\r
LanguageString languageString = getEcologyAll().get(language);\r
return (languageString == null ? null : languageString.getText());\r
}\r
-// public String getEcologyPreferred(List<Language> languages){\r
-// LanguageString languageString = getEcologyAll().getPreferredLanguageString(languages);\r
-// return languageString.getText();\r
-// }\r
- public Map<Language, LanguageString> getEcologyAll(){\r
- if (ecology == null){\r
+\r
+ // public String getEcologyPreferred(List<Language> languages){\r
+ // LanguageString languageString =\r
+ // getEcologyAll().getPreferredLanguageString(languages);\r
+ // return languageString.getText();\r
+ // }\r
+ /**\r
+ * Returns a copy of the multilanguage text holding the ecology data.\r
+ * \r
+ * @see {@link TextData#getMultilanguageText()}\r
+ * @return\r
+ */\r
+ @Transient\r
+ public Map<Language, LanguageString> getEcologyAll() {\r
+ if (ecology == null) {\r
try {\r
- ecology = initializeFieldObjectTextDataWithSupportTest(Feature.ECOLOGY(), true, false);\r
+ ecology = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.ECOLOGY(), false, false);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
+ if (ecology == null) {\r
+ return new HashMap<Language, LanguageString>();\r
+ }\r
}\r
return ecology.getMultilanguageText();\r
}\r
- \r
- public void setEcology(String ecology){\r
+\r
+ public void setEcology(String ecology) {\r
setEcology(ecology, null);\r
}\r
- public void setEcology(String ecologyText, Language language){\r
- if (language == null){\r
+\r
+ public void setEcology(String ecologyText, Language language) {\r
+ if (language == null) {\r
language = Language.DEFAULT();\r
}\r
- if (ecology == null){\r
+ if (ecology == null) {\r
try {\r
- ecology = initializeFieldObjectTextDataWithSupportTest(Feature.ECOLOGY(), true, false);\r
+ ecology = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.ECOLOGY(), true, false);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
- if (ecologyText == null){\r
+ if (ecologyText == null) {\r
ecology.removeText(language);\r
- }else{\r
- ecology.putText(ecologyText, language);\r
+ } else {\r
+ ecology.putText(language, ecologyText);\r
}\r
}\r
- public void removeEcology(Language language){\r
+\r
+ public void removeEcology(Language language) {\r
setEcology(null, language);\r
}\r
+\r
/**\r
* Removes ecology for the default language\r
*/\r
- public void removeEcology(){\r
+ public void removeEcology() {\r
setEcology(null, null);\r
}\r
- public void removeEcologyAll(){\r
- \r
+\r
+ public void removeEcologyAll() {\r
+\r
}\r
\r
- \r
- //plant description\r
- public String getPlantDescription(){\r
+ // plant description\r
+ @Transient\r
+ public String getPlantDescription() {\r
return getPlantDescription(null);\r
}\r
- public String getPlantDescription(Language language){\r
- if (language == null){\r
+\r
+ public String getPlantDescription(Language language) {\r
+ if (language == null) {\r
language = Language.DEFAULT();\r
}\r
LanguageString languageString = getPlantDescriptionAll().get(language);\r
return (languageString == null ? null : languageString.getText());\r
}\r
-// public String getPlantDescriptionPreferred(List<Language> languages){\r
-// LanguageString languageString = getPlantDescriptionAll().getPreferredLanguageString(languages);\r
-// return languageString.getText();\r
-// }\r
- public Map<Language, LanguageString> getPlantDescriptionAll(){\r
- if (plantDescription == null){\r
+\r
+ // public String getPlantDescriptionPreferred(List<Language> languages){\r
+ // LanguageString languageString =\r
+ // getPlantDescriptionAll().getPreferredLanguageString(languages);\r
+ // return languageString.getText();\r
+ // }\r
+ /**\r
+ * Returns a copy of the multilanguage text holding the description data.\r
+ * \r
+ * @see {@link TextData#getMultilanguageText()}\r
+ * @return\r
+ */\r
+ @Transient\r
+ public Map<Language, LanguageString> getPlantDescriptionAll() {\r
+ if (plantDescription == null) {\r
try {\r
- plantDescription = initializeFieldObjectTextDataWithSupportTest(Feature.DESCRIPTION(), true, false);\r
+ plantDescription = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.DESCRIPTION(), false, false);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
+ if (plantDescription == null) {\r
+ return new HashMap<Language, LanguageString>();\r
+ }\r
}\r
return plantDescription.getMultilanguageText();\r
}\r
- public void setPlantDescription(String plantDescription){\r
+\r
+ public void setPlantDescription(String plantDescription) {\r
setPlantDescription(plantDescription, null);\r
}\r
- public void setPlantDescription(String plantDescriptionText, Language language){\r
- if (language == null){\r
+\r
+ public void setPlantDescription(String plantDescriptionText,\r
+ Language language) {\r
+ if (language == null) {\r
language = Language.DEFAULT();\r
}\r
- if (plantDescription == null){\r
+ if (plantDescription == null) {\r
try {\r
- plantDescription = initializeFieldObjectTextDataWithSupportTest(Feature.DESCRIPTION(), true, false);\r
+ plantDescription = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.DESCRIPTION(), true, false);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
- if (plantDescriptionText == null){\r
+ if (plantDescriptionText == null) {\r
plantDescription.removeText(language);\r
- }else{\r
- plantDescription.putText(plantDescriptionText, language);\r
+ } else {\r
+ plantDescription.putText(language, plantDescriptionText);\r
}\r
}\r
- public void removePlantDescription(Language language){\r
+\r
+ public void removePlantDescription(Language language) {\r
setPlantDescription(null, language);\r
}\r
- \r
\r
- \r
- //field object definition\r
+ // field object definition\r
public void addFieldObjectDefinition(String text, Language language) {\r
- getFieldObservation(true).addDefinition(text, language);\r
+ getFieldUnit(true).putDefinition(language, text);\r
}\r
+\r
+ @Transient\r
public Map<Language, LanguageString> getFieldObjectDefinition() {\r
- if (! hasFieldObservation()){\r
+ if (!hasFieldUnit()) {\r
return new HashMap<Language, LanguageString>();\r
- }else{\r
- return getFieldObservation(true).getDefinition();\r
+ } else {\r
+ return getFieldUnit(true).getDefinition();\r
}\r
}\r
+\r
public String getFieldObjectDefinition(Language language) {\r
Map<Language, LanguageString> map = getFieldObjectDefinition();\r
- LanguageString languageString = (map == null? null : map.get(language));\r
- if (languageString != null){\r
+ LanguageString languageString = (map == null ? null : map.get(language));\r
+ if (languageString != null) {\r
return languageString.getText();\r
- }else {\r
+ } else {\r
return null;\r
}\r
}\r
+\r
public void removeFieldObjectDefinition(Language lang) {\r
- if (hasFieldObservation()){\r
- getFieldObservation(true).removeDefinition(lang);\r
+ if (hasFieldUnit()) {\r
+ getFieldUnit(true).removeDefinition(lang);\r
}\r
}\r
- \r
\r
- //media\r
- public boolean addFieldObjectMedia(Media media) {\r
+ // media\r
+ public boolean addFieldObjectMedia(Media media) {\r
try {\r
- return addMedia(media, getFieldObservation(true));\r
+ return addMedia(media, getFieldUnit(true));\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
+\r
/**\r
* Returns true, if an image gallery for the field object exists.<BR>\r
- * Returns also <code>true</code> if the image gallery is empty. \r
+ * Returns also <code>true</code> if the image gallery is empty.\r
+ * \r
* @return\r
*/\r
- public boolean hasFieldObjectImageGallery(){\r
- if (! hasFieldObject()){\r
+ public boolean hasFieldObjectImageGallery() {\r
+ if (!hasFieldObject()) {\r
return false;\r
- }else{\r
- return (getImageGallery(fieldObservation, false) != null);\r
+ } else {\r
+ return (getImageGallery(fieldUnit, false) != null);\r
}\r
}\r
- \r
+\r
+ public void setFieldObjectImageGallery(SpecimenDescription imageGallery)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ SpecimenDescription existingGallery = getFieldObjectImageGallery(false);\r
+\r
+ // test attached specimens contain this.derivedUnit\r
+ SpecimenOrObservationBase<?> facadeFieldUnit = innerFieldUnit();\r
+ testSpecimenInImageGallery(imageGallery, facadeFieldUnit);\r
+\r
+ if (existingGallery != null) {\r
+ if (existingGallery != imageGallery) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "DerivedUnitFacade does not allow more than one image gallery");\r
+ } else {\r
+ // do nothing\r
+ }\r
+ } else {\r
+ TextData textData = testImageGallery(imageGallery);\r
+ this.fieldObjectMediaTextData = textData;\r
+ }\r
+ }\r
+\r
/**\r
+ * Returns the field object image gallery. If no such image gallery exists\r
+ * and createIfNotExists is true an new one is created. Otherwise null is\r
+ * returned.\r
+ * \r
* @param createIfNotExists\r
* @return\r
*/\r
- public SpecimenDescription getFieldObjectImageGallery(boolean createIfNotExists){\r
+ public SpecimenDescription getFieldObjectImageGallery(\r
+ boolean createIfNotExists) {\r
TextData textData;\r
try {\r
- textData = initializeFieldObjectTextDataWithSupportTest(Feature.IMAGE(), createIfNotExists, true);\r
+ textData = initializeFieldObjectTextDataWithSupportTest(\r
+ Feature.IMAGE(), createIfNotExists, true);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
- if (textData != null){\r
- return CdmBase.deproxy(textData.getInDescription(), SpecimenDescription.class);\r
- }else{\r
+ if (textData != null) {\r
+ return CdmBase.deproxy(textData.getInDescription(),\r
+ SpecimenDescription.class);\r
+ } else {\r
return null;\r
}\r
}\r
+\r
/**\r
* Returns the media for the field object.<BR>\r
+ * \r
* @return\r
*/\r
+ @Transient\r
public List<Media> getFieldObjectMedia() {\r
try {\r
- List<Media> result = getMedia(getFieldObservation(false), false);\r
+ List<Media> result = getMediaList(getFieldUnit(false), false);\r
return result == null ? new ArrayList<Media>() : result;\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
+\r
public boolean removeFieldObjectMedia(Media media) {\r
try {\r
- return removeMedia(media, getFieldObservation(false));\r
+ return removeMedia(media, getFieldUnit(false));\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
\r
- //field number\r
+ // field number\r
+ @Transient\r
public String getFieldNumber() {\r
- if (! hasFieldObservation()){\r
+ if (!hasFieldUnit()) {\r
return null;\r
- }else{\r
- return getFieldObservation(true).getFieldNumber();\r
+ } else {\r
+ return getFieldUnit(true).getFieldNumber();\r
}\r
}\r
+\r
public void setFieldNumber(String fieldNumber) {\r
- getFieldObservation(true).setFieldNumber(fieldNumber);\r
+ getFieldUnit(true).setFieldNumber(fieldNumber);\r
}\r
\r
- \r
- //field notes\r
+ // primary collector\r
+ @Transient\r
+ public Person getPrimaryCollector() {\r
+ if (!hasFieldUnit()) {\r
+ return null;\r
+ } else {\r
+ return getFieldUnit(true).getPrimaryCollector();\r
+ }\r
+ }\r
+\r
+ public void setPrimaryCollector(Person primaryCollector) {\r
+ getFieldUnit(true).setPrimaryCollector(primaryCollector);\r
+ }\r
+\r
+ // field notes\r
+ @Transient\r
public String getFieldNotes() {\r
- if (! hasFieldObservation()){\r
+ if (!hasFieldUnit()) {\r
return null;\r
- }else{\r
- return getFieldObservation(true).getFieldNotes();\r
+ } else {\r
+ return getFieldUnit(true).getFieldNotes();\r
}\r
}\r
+\r
public void setFieldNotes(String fieldNotes) {\r
- getFieldObservation(true).setFieldNotes(fieldNotes);\r
+ getFieldUnit(true).setFieldNotes(fieldNotes);\r
}\r
\r
-\r
- //individual counts\r
+ // individual counts\r
+ @Transient\r
public Integer getIndividualCount() {\r
- return (hasFieldObservation()? getFieldObservation(true).getIndividualCount() : null );\r
+ return (hasFieldUnit() ? getFieldUnit(true).getIndividualCount() : null);\r
}\r
+\r
public void setIndividualCount(Integer individualCount) {\r
- getFieldObservation(true).setIndividualCount(individualCount);\r
+ getFieldUnit(true).setIndividualCount(individualCount);\r
}\r
\r
- //life stage\r
- public Stage getLifeStage() {\r
- return (hasFieldObservation()? getFieldObservation(true).getLifeStage() : null );\r
+ // life stage\r
+ @Transient\r
+ public DefinedTerm getLifeStage() {\r
+ return (hasFieldUnit() ? getFieldUnit(true).getLifeStage() : null);\r
}\r
- public void setLifeStage(Stage lifeStage) {\r
- getFieldObservation(true).setLifeStage(lifeStage);\r
+\r
+ public void setLifeStage(DefinedTerm lifeStage) {\r
+ getFieldUnit(true).setLifeStage(lifeStage);\r
}\r
\r
- //sex\r
- public Sex getSex() {\r
- return (hasFieldObservation()? getFieldObservation(true).getSex() : null );\r
+ // sex\r
+ @Transient\r
+ public DefinedTerm getSex() {\r
+ return (hasFieldUnit() ? getFieldUnit(true).getSex(): null);\r
}\r
- public void setSex(Sex sex) {\r
- getFieldObservation(true).setSex(sex);\r
+\r
+ public void setSex(DefinedTerm sex) {\r
+ getFieldUnit(true).setSex(sex);\r
}\r
\r
- \r
- //field observation\r
- public boolean hasFieldObservation(){\r
- return (getFieldObservation(false) != null);\r
+ // kind of Unit\r
+ @Transient\r
+ public DefinedTerm getKindOfUnit() {\r
+ return (hasFieldUnit() ? getFieldUnit(true).getKindOfUnit() : null);\r
+ }\r
+\r
+ public void setKindOfUnit(DefinedTerm kindOfUnit) {\r
+ getFieldUnit(true).setKindOfUnit(kindOfUnit);\r
}\r
\r
+\r
+ // field unit\r
+ public boolean hasFieldUnit() {\r
+ return (getFieldUnit(false) != null);\r
+ }\r
+\r
/**\r
- * Returns the field observation as an object.\r
+ * Returns the field unit as an object.\r
+ * \r
* @return\r
*/\r
- public FieldObservation getFieldObservation(){\r
- return getFieldObservation(false);\r
+ public FieldUnit innerFieldUnit() {\r
+ return getFieldUnit(false);\r
}\r
\r
/**\r
- * Returns the field observation as an object.\r
+ * Returns the field unit as an object.\r
+ * \r
* @return\r
*/\r
- public FieldObservation getFieldObservation(boolean createIfNotExists){\r
- if (fieldObservation == null && createIfNotExists){\r
- fieldObservation = FieldObservation.NewInstance();\r
- DerivationEvent derivationEvent = getDerivationEvent(true);\r
- derivationEvent.addOriginal(fieldObservation);\r
+ public FieldUnit getFieldUnit(boolean createIfNotExists) {\r
+ if (fieldUnit == null && createIfNotExists) {\r
+ setFieldUnit(FieldUnit.NewInstance());\r
}\r
- return this.fieldObservation;\r
+ return this.fieldUnit;\r
}\r
-\r
\r
\r
-//****************** Specimen ************************************************** \r
- \r
- //Definition\r
+ private void setFieldUnit(FieldUnit fieldUnit) {\r
+ this.fieldUnit = fieldUnit;\r
+ if (fieldUnit != null){\r
+ if (config.isFirePropertyChangeEvents()){\r
+ addNewEventPropagationListener(fieldUnit);\r
+ }\r
+ if (derivedUnit != null){\r
+ DerivationEvent derivationEvent = getDerivationEvent(CREATE);\r
+ derivationEvent.addOriginal(fieldUnit);\r
+ }\r
+ setFieldUnitCacheStrategy();\r
+ }\r
+ }\r
+\r
+ // ****************** Specimen *******************************************\r
+\r
+ // Definition\r
public void addDerivedUnitDefinition(String text, Language language) {\r
- derivedUnit.addDefinition(text, language);\r
+ innerDerivedUnit().putDefinition(language, text);\r
}\r
- public Map<Language, LanguageString> getDerivedUnitDefinitions(){\r
+\r
+ @Transient\r
+ public Map<Language, LanguageString> getDerivedUnitDefinitions() {\r
+ testDerivedUnit();\r
return this.derivedUnit.getDefinition();\r
}\r
+\r
+\r
public String getDerivedUnitDefinition(Language language) {\r
- Map<Language,LanguageString> languageMap = derivedUnit.getDefinition();\r
+ testDerivedUnit();\r
+ Map<Language, LanguageString> languageMap = derivedUnit.getDefinition();\r
LanguageString languageString = languageMap.get(language);\r
- if (languageString != null){\r
+ if (languageString != null) {\r
return languageString.getText();\r
- }else {\r
+ } else {\r
return null;\r
}\r
}\r
+\r
public void removeDerivedUnitDefinition(Language lang) {\r
+ testDerivedUnit();\r
derivedUnit.removeDefinition(lang);\r
}\r
\r
- //Determination\r
+ // Determination\r
public void addDetermination(DeterminationEvent determination) {\r
+ testDerivedUnit();\r
+ //TODO implement correct bidirectional mapping in model classes\r
+ determination.setIdentifiedUnit(derivedUnit);\r
derivedUnit.addDetermination(determination);\r
}\r
+\r
+ @Transient\r
+ public DeterminationEvent getPreferredDetermination() {\r
+ testDerivedUnit();\r
+ Set<DeterminationEvent> events = derivedUnit.getDeterminations();\r
+ for (DeterminationEvent event : events){\r
+ if (event.getPreferredFlag() == true){\r
+ return event;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ /**\r
+ * This method returns the preferred determination.\r
+ * @see #getOtherDeterminations()\r
+ * @see #getDeterminations()\r
+ * @return\r
+ */\r
+ @Transient\r
+ public void setPreferredDetermination(DeterminationEvent newEvent) {\r
+ testDerivedUnit();\r
+ Set<DeterminationEvent> events = derivedUnit.getDeterminations();\r
+ for (DeterminationEvent event : events){\r
+ if (event.getPreferredFlag() == true){\r
+ event.setPreferredFlag(false);\r
+ }\r
+ }\r
+ newEvent.setPreferredFlag(true);\r
+ events.add(newEvent);\r
+ }\r
+ \r
+ /**\r
+ * This method returns all determinations except for the preferred one.\r
+ * @see #getPreferredDetermination()\r
+ * @see #getDeterminations()\r
+ * @return\r
+ */\r
+ @Transient\r
+ public Set<DeterminationEvent> getOtherDeterminations() {\r
+ testDerivedUnit();\r
+ Set<DeterminationEvent> events = derivedUnit.getDeterminations();\r
+ Set<DeterminationEvent> result = new HashSet<DeterminationEvent>();\r
+ for (DeterminationEvent event : events){\r
+ if (event.getPreferredFlag() != true){\r
+ result.add(event);\r
+ }\r
+ }\r
+ return result;\r
+ }\r
+ \r
+ /**\r
+ * This method returns all determination events. The preferred one {@link #getPreferredDetermination()} \r
+ * and all others {@link #getOtherDeterminations()}.\r
+ * @return\r
+ */\r
+ @Transient\r
public Set<DeterminationEvent> getDeterminations() {\r
+ testDerivedUnit();\r
return derivedUnit.getDeterminations();\r
}\r
+\r
public void removeDetermination(DeterminationEvent determination) {\r
+ testDerivedUnit();\r
derivedUnit.removeDetermination(determination);\r
}\r
- \r
- //Media\r
- public boolean addDerivedUnitMedia(Media media) {\r
+\r
+ // Media\r
+ public boolean addDerivedUnitMedia(Media media) {\r
+ testDerivedUnit();\r
try {\r
return addMedia(media, derivedUnit);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
+\r
/**\r
* Returns true, if an image gallery exists for the specimen.<BR>\r
- * Returns also <code>true</code> if the image gallery is empty. \r
+ * Returns also <code>true</code> if the image gallery is empty.\r
*/\r
- public boolean hasDerivedUnitImageGallery(){\r
+ public boolean hasDerivedUnitImageGallery() {\r
return (getImageGallery(derivedUnit, false) != null);\r
}\r
- \r
- public SpecimenDescription getDerivedUnitImageGallery(boolean createIfNotExists){\r
+\r
+ public SpecimenDescription getDerivedUnitImageGallery(boolean createIfNotExists) {\r
+ testDerivedUnit();\r
TextData textData;\r
try {\r
- textData = inititialzeTextDataWithSupportTest(Feature.IMAGE(), derivedUnit, createIfNotExists, true);\r
+ textData = inititializeTextDataWithSupportTest(Feature.IMAGE(),\r
+ derivedUnit, createIfNotExists, true);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
- if (textData != null){\r
- return CdmBase.deproxy(textData.getInDescription(), SpecimenDescription.class);\r
- }else{\r
+ if (textData != null) {\r
+ return CdmBase.deproxy(textData.getInDescription(),\r
+ SpecimenDescription.class);\r
+ } else {\r
return null;\r
}\r
}\r
- \r
+\r
+ public void setDerivedUnitImageGallery(SpecimenDescription imageGallery)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ testDerivedUnit();\r
+ SpecimenDescription existingGallery = getDerivedUnitImageGallery(false);\r
+\r
+ // test attached specimens contain this.derivedUnit\r
+ SpecimenOrObservationBase facadeDerivedUnit = innerDerivedUnit();\r
+ testSpecimenInImageGallery(imageGallery, facadeDerivedUnit);\r
+\r
+ if (existingGallery != null) {\r
+ if (existingGallery != imageGallery) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "DerivedUnitFacade does not allow more than one image gallery");\r
+ } else {\r
+ // do nothing\r
+ }\r
+ } else {\r
+ TextData textData = testImageGallery(imageGallery);\r
+ this.derivedUnitMediaTextData = textData;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @param imageGallery\r
+ * @throws DerivedUnitFacadeNotSupportedException\r
+ */\r
+ private void testSpecimenInImageGallery(SpecimenDescription imageGallery, SpecimenOrObservationBase specimen)\r
+ throws DerivedUnitFacadeNotSupportedException {\r
+ SpecimenOrObservationBase imageGallerySpecimen = imageGallery.getDescribedSpecimenOrObservation();\r
+ if (imageGallerySpecimen == null) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Image Gallery has no Specimen attached. Please attache according specimen or field unit.");\r
+ }\r
+ if (! imageGallerySpecimen.equals(specimen)) {\r
+ throw new DerivedUnitFacadeNotSupportedException(\r
+ "Image Gallery has not the facade's field object attached. Please add field object first " +\r
+ "to image gallery specimenOrObservation list.");\r
+ }\r
+ }\r
+\r
/**\r
* Returns the media for the specimen.<BR>\r
+ * \r
* @return\r
*/\r
+ @Transient\r
public List<Media> getDerivedUnitMedia() {\r
+ testDerivedUnit();\r
try {\r
- List<Media> result = getMedia(derivedUnit, false);\r
+ List<Media> result = getMediaList(derivedUnit, false);\r
return result == null ? new ArrayList<Media>() : result;\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
}\r
+\r
public boolean removeDerivedUnitMedia(Media media) {\r
+ testDerivedUnit();\r
try {\r
return removeMedia(media, derivedUnit);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
}\r
}\r
\r
- \r
- //Accession Number\r
+ // Accession Number\r
+ @Transient\r
public String getAccessionNumber() {\r
+ testDerivedUnit();\r
return derivedUnit.getAccessionNumber();\r
}\r
+\r
public void setAccessionNumber(String accessionNumber) {\r
+ testDerivedUnit();\r
derivedUnit.setAccessionNumber(accessionNumber);\r
}\r
\r
- //Catalog Number\r
+ @Transient\r
public String getCatalogNumber() {\r
+ testDerivedUnit();\r
return derivedUnit.getCatalogNumber();\r
}\r
+\r
public void setCatalogNumber(String catalogNumber) {\r
+ testDerivedUnit();\r
derivedUnit.setCatalogNumber(catalogNumber);\r
}\r
\r
- //Preservation Method\r
- \r
+ @Transient\r
+ public String getBarcode() {\r
+ testDerivedUnit();\r
+ return derivedUnit.getBarcode();\r
+ }\r
+\r
+ public void setBarcode(String barcode) {\r
+ testDerivedUnit();\r
+ derivedUnit.setBarcode(barcode);\r
+ }\r
+\r
+ // Preservation Method\r
+\r
/**\r
* Only supported by specimen and fossils\r
+ * \r
* @see #DerivedUnitType\r
* @return\r
*/\r
+ @Transient\r
public PreservationMethod getPreservationMethod() throws MethodNotSupportedByDerivedUnitTypeException {\r
- if (derivedUnit.isInstanceOf(Specimen.class)){\r
- return CdmBase.deproxy(derivedUnit, Specimen.class).getPreservation();\r
- }else{\r
- throw new MethodNotSupportedByDerivedUnitTypeException("A preservation method is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ testDerivedUnit();\r
+ if (derivedUnit.getRecordBasis().isPreservedSpecimen()) {\r
+ return CdmBase.deproxy(derivedUnit, DerivedUnit.class).getPreservation();\r
+ } else {\r
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()) {\r
+ throw new MethodNotSupportedByDerivedUnitTypeException(\r
+ "A preservation method is only available in derived units of type 'Preserved Specimen' or one of its specializations like 'Fossil Specimen' ");\r
+ } else {\r
+ return null;\r
+ }\r
}\r
}\r
+\r
/**\r
* Only supported by specimen and fossils\r
+ * \r
* @see #DerivedUnitType\r
* @return\r
*/\r
- public void setPreservationMethod(PreservationMethod preservation)throws MethodNotSupportedByDerivedUnitTypeException {\r
- if (derivedUnit.isInstanceOf(Specimen.class)){\r
- CdmBase.deproxy(derivedUnit, Specimen.class).setPreservation(preservation);\r
- }else{\r
- throw new MethodNotSupportedByDerivedUnitTypeException("A preservation method is only available in derived units of type 'Specimen' or 'Fossil'");\r
- \r
+ public void setPreservationMethod(PreservationMethod preservation)\r
+ throws MethodNotSupportedByDerivedUnitTypeException {\r
+ testDerivedUnit();\r
+ if (derivedUnit.getRecordBasis().isPreservedSpecimen()) {\r
+ CdmBase.deproxy(derivedUnit, DerivedUnit.class).setPreservation(preservation);\r
+ } else {\r
+ if (this.config\r
+ .isThrowExceptionForNonSpecimenPreservationMethodRequest()) {\r
+ throw new MethodNotSupportedByDerivedUnitTypeException(\r
+ "A preservation method is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ } else {\r
+ return;\r
+ }\r
}\r
}\r
\r
- //Stored under name\r
+ // Stored under name\r
+ @Transient\r
public TaxonNameBase getStoredUnder() {\r
+ testDerivedUnit();\r
return derivedUnit.getStoredUnder();\r
}\r
+\r
public void setStoredUnder(TaxonNameBase storedUnder) {\r
+ testDerivedUnit();\r
derivedUnit.setStoredUnder(storedUnder);\r
}\r
\r
- //colletors number\r
- public String getCollectorsNumber() {\r
- return derivedUnit.getCollectorsNumber();\r
+ // title cache\r
+ public String getTitleCache() {\r
+ SpecimenOrObservationBase<?> titledUnit = getTitledUnit();\r
+ \r
+ if (!titledUnit.isProtectedTitleCache()) {\r
+ // always compute title cache anew as long as there are no property\r
+ // change listeners on\r
+ // field unit, gathering event etc\r
+ titledUnit.setTitleCache(null, false);\r
+ }\r
+ return titledUnit.getTitleCache();\r
}\r
- public void setCollectorsNumber(String collectorsNumber) {\r
- this.derivedUnit.setCollectorsNumber(collectorsNumber);\r
+ \r
+ private SpecimenOrObservationBase<?> getTitledUnit(){\r
+ return (derivedUnit != null )? derivedUnit : fieldUnit;\r
}\r
\r
- //title cache\r
- public String getTitleCache() {\r
- if (! derivedUnit.isProtectedTitleCache()){\r
- //always compute title cache anew as long as there are no property change listeners on \r
- //field observation, gathering event etc \r
- derivedUnit.setTitleCache(null, false);\r
- }\r
- return this.derivedUnit.getTitleCache();\r
+ public boolean isProtectedTitleCache() {\r
+ return getTitledUnit().isProtectedTitleCache();\r
}\r
+\r
public void setTitleCache(String titleCache, boolean isProtected) {\r
- this.derivedUnit.setTitleCache(titleCache, isProtected);\r
+ this.getTitledUnit().setTitleCache(titleCache, isProtected);\r
}\r
\r
-\r
/**\r
* Returns the derived unit itself.\r
+ * \r
* @return the derived unit\r
*/\r
- public DerivedUnitBase getDerivedUnit() {\r
+ public DerivedUnit innerDerivedUnit() {\r
return this.derivedUnit;\r
}\r
\r
- private boolean hasDerivationEvent(){\r
+// /**\r
+// * Returns the derived unit itself.\r
+// * \r
+// * @return the derived unit\r
+// */\r
+// public DerivedUnit innerDerivedUnit(boolean createIfNotExists) {\r
+// DerivedUnit result = this.derivedUnit; \r
+// if (result == null && createIfNotExists){\r
+// if (this.fieldUnit == null){\r
+// String message = "Field unit must exist to create derived unit.";\r
+// throw new IllegalStateException(message);\r
+// }else{\r
+// DerivedUnit = \r
+// DerivationEvent derivationEvent = getDerivationEvent(true);\r
+// derivationEvent.addOriginal(fieldUnit);\r
+// return this.derivedUnit;\r
+// }\r
+// }\r
+// }\r
+\r
+ private boolean hasDerivationEvent() {\r
return getDerivationEvent() == null ? false : true;\r
}\r
- private DerivationEvent getDerivationEvent(){\r
+\r
+ private DerivationEvent getDerivationEvent() {\r
return getDerivationEvent(false);\r
}\r
- private DerivationEvent getDerivationEvent(boolean createIfNotExists){\r
- DerivationEvent result = derivedUnit.getDerivedFrom();\r
- if (result == null){\r
- result = DerivationEvent.NewInstance();\r
+\r
+ /**\r
+ * Returns the derivation event. If no derivation event exists and <code>createIfNotExists</code>\r
+ * is <code>true</code> a new derivation event is created and returned. \r
+ * Otherwise <code>null</code> is returned.\r
+ * @param createIfNotExists\r
+ */\r
+ private DerivationEvent getDerivationEvent(boolean createIfNotExists) {\r
+ DerivationEvent result = null;\r
+ if (derivedUnit != null){\r
+ result = derivedUnit.getDerivedFrom();\r
+ }else{\r
+ return null;\r
+ }\r
+ if (result == null && createIfNotExists) {\r
+ DerivationEventType type = null;\r
+ if (isAccessioned(derivedUnit)){\r
+ type = DerivationEventType.ACCESSIONING();\r
+ }\r
+ \r
+ result = DerivationEvent.NewInstance(type);\r
derivedUnit.setDerivedFrom(result);\r
}\r
return result;\r
}\r
- \r
- public String getExsiccatum() {\r
- logger.warn("Exsiccatum method not yet supported. Needs model change");\r
- return null;\r
+\r
+ /**\r
+ * TODO still unclear which classes do definetly require accessioning.\r
+ * Only return true for those classes which are clear.\r
+ * @param derivedUnit\r
+ * @return\r
+ */\r
+ private boolean isAccessioned(DerivedUnit derivedUnit) {\r
+ if (derivedUnit.getRecordBasis().equals(SpecimenOrObservationType.PreservedSpecimen) ){\r
+ return true; //maybe also subtypes should be true\r
+ }else{\r
+ return false;\r
+ }\r
}\r
- \r
- public String setExsiccatum() throws MethodNotSupportedException{\r
- throw new MethodNotSupportedException("Exsiccatum method not yet supported. Needs model change");\r
+\r
+ @Transient\r
+ public String getExsiccatum() throws MethodNotSupportedByDerivedUnitTypeException {\r
+ testDerivedUnit();\r
+ if (derivedUnit.getRecordBasis().isPreservedSpecimen()) {\r
+ return derivedUnit.getExsiccatum();\r
+ } else {\r
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()) {\r
+ throw new MethodNotSupportedByDerivedUnitTypeException(\r
+ "An exsiccatum is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
}\r
- \r
- \r
+\r
+ public void setExsiccatum(String exsiccatum) throws Exception {\r
+ testDerivedUnit();\r
+ if (derivedUnit.getRecordBasis().isPreservedSpecimen()) {\r
+ derivedUnit.setExsiccatum(exsiccatum);\r
+ } else {\r
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()) {\r
+ throw new MethodNotSupportedByDerivedUnitTypeException(\r
+ "An exsiccatum is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ } else {\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
// **** sources **/\r
- public void addSource(IdentifiableSource source){\r
+ public void addSource(IdentifiableSource source) {\r
+ testDerivedUnit();\r
this.derivedUnit.addSource(source);\r
}\r
+\r
/**\r
- * Creates an orignal source, adds it to the specimen and returns it.\r
+ * Creates an {@link IOriginalSource orignal source} or type , \r
+ * adds it to the specimen and returns it.\r
+ * \r
* @param reference\r
* @param microReference\r
* @param originalNameString\r
* @return\r
*/\r
- public IdentifiableSource addSource(ReferenceBase reference, String microReference, String originalNameString){\r
- IdentifiableSource source = IdentifiableSource.NewInstance(reference, microReference);\r
+ public IdentifiableSource addSource(OriginalSourceType type, Reference reference, String microReference, String originalNameString) {\r
+ IdentifiableSource source = IdentifiableSource.NewInstance(type, null, null, reference, microReference);\r
source.setOriginalNameString(originalNameString);\r
- derivedUnit.addSource(source);\r
+ addSource(source);\r
return source;\r
}\r
- \r
- public Set<IdentifiableSource> getSources(){\r
+\r
+ @Transient\r
+ public Set<IdentifiableSource> getSources() {\r
+ testDerivedUnit();\r
return derivedUnit.getSources();\r
}\r
\r
- public void removeSource(IdentifiableSource source){\r
+ public void removeSource(IdentifiableSource source) {\r
+ testDerivedUnit();\r
this.derivedUnit.removeSource(source);\r
}\r
- \r
- \r
+\r
/**\r
* @return the collection\r
*/\r
+ @Transient\r
public Collection getCollection() {\r
+ testDerivedUnit();\r
return derivedUnit.getCollection();\r
}\r
\r
-\r
/**\r
- * @param collection the collection to set\r
+ * @param collection\r
+ * the collection to set\r
*/\r
public void setCollection(Collection collection) {\r
+ testDerivedUnit();\r
derivedUnit.setCollection(collection);\r
}\r
+\r
+ // annotation\r
+ public void addAnnotation(Annotation annotation) {\r
+ testDerivedUnit();\r
+ this.derivedUnit.addAnnotation(annotation);\r
+ }\r
+\r
+ @Transient\r
+ public void getAnnotations() {\r
+ testDerivedUnit();\r
+ this.derivedUnit.getAnnotations();\r
+ }\r
+\r
+ public void removeAnnotation(Annotation annotation) {\r
+ testDerivedUnit();\r
+ this.derivedUnit.removeAnnotation(annotation);\r
+ }\r
+\r
+ // ******************************* Events ***************************\r
\r
+ //set of events that were currently fired by this facades field unit\r
+ //to avoid recursive fireing of the same event\r
+ private Set<PropertyChangeEvent> fireingEvents = new HashSet<PropertyChangeEvent>();\r
\r
+ /**\r
+ * @return\r
+ */\r
+ private void addNewEventPropagationListener(CdmBase listeningObject) {\r
+ //if there is already a listener, don't do anything\r
+ for (PropertyChangeListener listener : this.listeners.keySet()){\r
+ if (listeners.get(listener) == listeningObject){\r
+ return;\r
+ }\r
+ }\r
+ //create new listener\r
+ PropertyChangeListener listener = new PropertyChangeListener() {\r
+ @Override\r
+ public void propertyChange(PropertyChangeEvent event) {\r
+ if (derivedUnit != null){\r
+ derivedUnit.firePropertyChange(event);\r
+ }else{\r
+ if (! event.getSource().equals(fieldUnit) && ! fireingEvents.contains(event) ){\r
+ fireingEvents.add(event);\r
+ fieldUnit.firePropertyChange(event);\r
+ fireingEvents.remove(event);\r
+ }\r
+ }\r
+ }\r
+ };\r
+ //add listener to listening object and to list of listeners\r
+ listeningObject.addPropertyChangeListener(listener);\r
+ listeners.put(listener, listeningObject);\r
+ }\r
\r
- \r
+ // **************** Other Collections ********************************\r
\r
-//**************** Other Collections *************************************************** \r
- \r
/**\r
* Creates a duplicate specimen which derives from the same derivation event\r
- * as the facade specimen and adds collection data to it (all data available in\r
- * DerivedUnitBase and Specimen. Data from SpecimenOrObservationBase and above\r
- * are not yet shared at the moment. \r
+ * as the facade specimen and adds collection data to it (all data available\r
+ * in DerivedUnit and Specimen. Data from SpecimenOrObservationBase and\r
+ * above are not yet shared at the moment.\r
+ * \r
* @param collection\r
* @param catalogNumber\r
* @param accessionNumber\r
* @param preservation\r
* @return\r
*/\r
- public Specimen addDuplicate(Collection collection, String catalogNumber, String accessionNumber, \r
- String collectorsNumber, TaxonNameBase storedUnder, PreservationMethod preservation){\r
- Specimen duplicate = Specimen.NewInstance();\r
- duplicate.setDerivedFrom(getDerivationEvent(true));\r
+ public DerivedUnit addDuplicate(Collection collection, String catalogNumber,\r
+ String accessionNumber, TaxonNameBase storedUnder, PreservationMethod preservation) {\r
+ testDerivedUnit();\r
+ DerivedUnit duplicate = DerivedUnit.NewPreservedSpecimenInstance();\r
+ duplicate.setDerivedFrom(getDerivationEvent(CREATE));\r
duplicate.setCollection(collection);\r
duplicate.setCatalogNumber(catalogNumber);\r
duplicate.setAccessionNumber(accessionNumber);\r
- duplicate.setCollectorsNumber(collectorsNumber);\r
duplicate.setStoredUnder(storedUnder);\r
duplicate.setPreservation(preservation);\r
return duplicate;\r
}\r
- \r
- public void addDuplicate(DerivedUnitBase duplicateSpecimen){\r
- //TODO check derivedUnitType\r
- getDerivationEvent(true).addDerivative(duplicateSpecimen); \r
- }\r
- public Set<Specimen> getDuplicates(){\r
- Set<Specimen> result = new HashSet<Specimen>();\r
- if (hasDerivationEvent()){\r
- for (DerivedUnitBase derivedUnit: getDerivationEvent(true).getDerivatives()){\r
- if (derivedUnit.isInstanceOf(Specimen.class) && ! derivedUnit.equals(this.derivedUnit)){\r
- result.add(CdmBase.deproxy(derivedUnit, Specimen.class));\r
+\r
+ public void addDuplicate(DerivedUnit duplicateSpecimen) {\r
+ // TODO check derivedUnitType\r
+ testDerivedUnit();\r
+ getDerivationEvent(CREATE).addDerivative(duplicateSpecimen);\r
+ }\r
+\r
+ @Transient\r
+ public Set<DerivedUnit> getDuplicates() {\r
+ testDerivedUnit();\r
+ Set<DerivedUnit> result = new HashSet<DerivedUnit>();\r
+ if (hasDerivationEvent()) {\r
+ for (DerivedUnit derivedUnit : getDerivationEvent(CREATE)\r
+ .getDerivatives()) {\r
+ if (derivedUnit.isInstanceOf(DerivedUnit.class)\r
+ && !derivedUnit.equals(this.derivedUnit)) {\r
+ result.add(CdmBase.deproxy(derivedUnit, DerivedUnit.class));\r
}\r
}\r
}\r
return result;\r
}\r
- public void removeDuplicate(Specimen duplicateSpecimen){\r
- if (hasDerivationEvent()){\r
- getDerivationEvent(true).removeDerivative(duplicateSpecimen);\r
+\r
+ public void removeDuplicate(DerivedUnit duplicateSpecimen) {\r
+ testDerivedUnit();\r
+ if (hasDerivationEvent()) {\r
+ getDerivationEvent(CREATE).removeDerivative(duplicateSpecimen);\r
}\r
}\r
\r
\r
+\r
+ private void testDerivedUnit() {\r
+ if (derivedUnit == null){\r
+ throw new IllegalStateException("This method is not allowed for this specimen or observation type. Probably you have tried to add specimen(derived unit) information to a field unit");\r
+ }\r
+ }\r
+\r
+ public void setType(SpecimenOrObservationType type) {\r
+ this.type = type;\r
+ }\r
+\r
+ public SpecimenOrObservationType getType() {\r
+ return type;\r
+ }\r
+\r
+ \r
+ /**\r
+ * Closes this facade. As a minimum this method removes all listeners created by this facade from their \r
+ * listening objects.\r
+ */\r
+ public void close(){\r
+ for (PropertyChangeListener listener : this.listeners.keySet()){\r
+ CdmBase listeningObject = listeners.get(listener);\r
+ listeningObject.removePropertyChangeListener(listener);\r
+ }\r
+ }\r
\r
\r
+ /**\r
+ * Computes the correct distance string for given values for min, max and text.\r
+ * If text is not blank, text is returned, otherwise "min - max" or a single value is returned.\r
+ * @param min min value as number \r
+ * @param max max value as number\r
+ * @param text text representation of distance\r
+ * @return the formatted distance string\r
+ */\r
+ private String distanceString(Number min, Number max, String text) {\r
+ if (StringUtils.isNotBlank(text)){\r
+ return text;\r
+ }else{\r
+ String minStr = min == null? null : String.valueOf(min);\r
+ String maxStr = max == null? null : String.valueOf(max);\r
+ String result = CdmUtils.concat(UTF8.EN_DASH_SPATIUM.toString(), minStr, maxStr);\r
+ return result;\r
+ }\r
+ }\r
}\r