\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.log4j.Logger;\r
\r
+import eu.etaxonomy.cdm.api.service.IOccurrenceService;\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.IdentifiableSource;\r
import eu.etaxonomy.cdm.model.common.Language;\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.reference.Reference;\r
\r
/**\r
* This class is a facade to the eu.etaxonomy.cdm.model.occurrence package from\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
- \r
/**\r
* Enum that defines the class the "Specimen" belongs to.\r
* Some methods of the facade are not available for certain classes\r
private TextData ecology;\r
private TextData plantDescription;\r
\r
+ \r
+ /**\r
+ * Creates a derived unit facade for a new derived unit of type <code>type</code>.\r
+ * @param type\r
+ * @return\r
+ */\r
public static DerivedUnitFacade NewInstance(DerivedUnitType type){\r
return new DerivedUnitFacade(type);\r
}\r
\r
+ /**\r
+ * Creates a derived unit facade for a given derived unit using the default configuration.\r
+ * @param derivedUnit\r
+ * @return\r
+ * @throws DerivedUnitFacadeNotSupportedException\r
+ */\r
public static DerivedUnitFacade NewInstance(DerivedUnitBase derivedUnit) throws DerivedUnitFacadeNotSupportedException{\r
- return new DerivedUnitFacade(derivedUnit, null, DerivedUnitType.Specimen);\r
+ return new DerivedUnitFacade(derivedUnit, null);\r
}\r
\r
public static DerivedUnitFacade NewInstance(DerivedUnitBase derivedUnit, DerivedUnitFacadeConfigurator config) throws DerivedUnitFacadeNotSupportedException{\r
- return new DerivedUnitFacade(derivedUnit, config, DerivedUnitType.Specimen);\r
+ return new DerivedUnitFacade(derivedUnit, config);\r
}\r
\r
+\r
+ \r
// ****************** CONSTRUCTOR ****************************************************\r
\r
private DerivedUnitFacade(DerivedUnitType type){\r
setCacheStrategy();\r
}\r
\r
- private DerivedUnitFacade(DerivedUnitBase derivedUnit, DerivedUnitFacadeConfigurator config, DerivedUnitType type) throws DerivedUnitFacadeNotSupportedException{\r
- //this.type = type; ??\r
+ private DerivedUnitFacade(DerivedUnitBase derivedUnit, DerivedUnitFacadeConfigurator config) throws DerivedUnitFacadeNotSupportedException{\r
\r
if (config == null){\r
config = DerivedUnitFacadeConfigurator.NewInstance();\r
//fieldObservation = FieldObservation.NewInstance();\r
}else if (fieldOriginals.size() == 1){\r
fieldObservation = fieldOriginals.iterator().next();\r
+ //###fieldObservation = getInitializedFieldObservation(fieldObservation);\r
+ fieldObservation.addPropertyChangeListener(getNewEventPropagationListener());\r
}else{\r
throw new IllegalStateException("Illegal state");\r
} \r
}\r
+ // #### derivedUnit = getInitializedDerivedUnit(derivedUnit);\r
\r
//test if unsupported\r
\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
+ this.derivedUnitMediaTextData = inititializeTextDataWithSupportTest(Feature.IMAGE(), this.derivedUnit, false, true);\r
\r
//field observation\r
// objectTypeExceptionText = "Field observation";\r
}\r
\r
\r
+ private DerivedUnitBase getInitializedDerivedUnit(DerivedUnitBase derivedUnit) {\r
+ IOccurrenceService occurrenceService = this.config.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
+ DerivedUnitBase result = (DerivedUnitBase)occurrenceService.load(derivedUnit.getUuid(), propertyPaths);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Initializes the derived unit according to the configuartions property path.\r
+ * If the property path is <code>null</code> or no occurrence service is given the\r
+ * returned object is the same as the input parameter.\r
+ * @param fieldObservation2\r
+ * @return\r
+ */\r
+ private FieldObservation getInitializedFieldObservation(FieldObservation fieldObservation) {\r
+ IOccurrenceService occurrenceService = this.config.getOccurrenceService();\r
+ if (occurrenceService == null){\r
+ return fieldObservation;\r
+ }\r
+ List<String> propertyPaths = this.config.getPropertyPaths();\r
+ if (propertyPaths == null){\r
+ return fieldObservation;\r
+ }\r
+ propertyPaths = getFieldObjectPropertyPaths(propertyPaths);\r
+ FieldObservation result = (FieldObservation)occurrenceService.load(fieldObservation.getUuid(), propertyPaths);\r
+ return result;\r
+ }\r
+\r
+ /**\r
+ * Transforms the property paths in a way that the facade is handled just like an \r
+ * ordinary CdmBase object.<BR>\r
+ * E.g. a property path "collectinAreas" will be translated into gatheringEvent.collectingAreas\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", "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", "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", "description");\r
+ result.add(facadePath);\r
+ }\r
+ // fieldObjectMedia (Media)\r
+ else if (facadePath.startsWith("fieldObjectMedia")){\r
+ // TODO ??? \r
+ facadePath = facadePath.replace("fieldObjectMedia", "descriptions.elements.media");\r
+ result.add(facadePath);\r
+ }\r
+ \r
+ //Gathering Event will always be added\r
+ result.add("gatheringEvent");\r
+ \r
+ }\r
+ \r
+/*\r
+ Gathering Event\r
+ ====================\r
+ - gatheringEvent (GatheringEvent)\r
+\r
+ Field Object\r
+ =================\r
+ - ecology/ ecologyAll (String) ???\r
+ - plant description (like ecology)\r
+ \r
+ - fieldObjectImageGallery (SpecimenDescription) - is automatically initialized via fieldObjectMedia\r
+\r
+*/\r
+ \r
+ return result;\r
+ }\r
+ \r
+ /**\r
+ * Transforms the property paths in a way that the facade is handled just like an \r
+ * ordinary CdmBase object.<BR>\r
+ * E.g. a property path "collectinAreas" will be translated into gatheringEvent.collectingAreas\r
+ * \r
+ * Not needed (?) as the facade works with REST service property paths without using this method.\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", "description");\r
+ result.add(facadePath);\r
+ }\r
+ \r
+ // derivedUnitMedia (Media)\r
+ else if (facadePath.startsWith("derivedUnitMedia")){\r
+ // TODO ??? \r
+ facadePath = facadePath.replace("derivedUnitMedia", "descriptions.elements.media");\r
+ result.add(facadePath);\r
+ }\r
+ \r
+ }\r
+ \r
+/*\r
+ //TODO\r
+ Derived Unit\r
+ =====================\r
+ \r
+ - derivedUnitImageGallery (SpecimenDescription) - is automatically 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
private void setCacheStrategy() {\r
+ if (derivedUnit == null){\r
+ throw new NullPointerException("Facade's derviedUnit must not be null to set cache strategy");\r
+ }\r
derivedUnit.setCacheStrategy(new DerivedUnitFacadeCacheStrategy());\r
}\r
\r
if (fieldObject == null){\r
return null;\r
}\r
- return inititialzeTextDataWithSupportTest(feature, fieldObject, createIfNotExists, isImageGallery);\r
+ return inititializeTextDataWithSupportTest(feature, fieldObject, createIfNotExists, isImageGallery);\r
}\r
\r
\r
* @return\r
* @throws DerivedUnitFacadeNotSupportedException\r
*/\r
- private TextData inititialzeTextDataWithSupportTest(Feature feature, SpecimenOrObservationBase specimen, boolean createIfNotExists, \r
+ private TextData inititializeTextDataWithSupportTest(Feature feature, SpecimenOrObservationBase specimen, boolean createIfNotExists, \r
boolean isImageGallery) throws DerivedUnitFacadeNotSupportedException {\r
if (feature == null ){\r
return null;\r
return textData;\r
}\r
}\r
+ \r
+\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.\r
+ * If the given image gallery does not have text data attached, it is created and attached.\r
+ * @param imageGallery\r
+ * @return\r
+ * @throws DerivedUnitFacadeNotSupportedException\r
+ */\r
+ private TextData testImageGallery(SpecimenDescription imageGallery) throws DerivedUnitFacadeNotSupportedException {\r
+ if (imageGallery.isImageGallery() == false){\r
+ throw new DerivedUnitFacadeNotSupportedException("Image gallery needs to have image gallery flag set");\r
+ }\r
+ if (imageGallery.getElements().size() > 1){\r
+ throw new DerivedUnitFacadeNotSupportedException("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().isInstanceOf(TextData.class)){\r
+ throw new DerivedUnitFacadeNotSupportedException("Image gallery must only have TextData as element");\r
+ }else{\r
+ textData = CdmBase.deproxy(imageGallery.getElements().iterator().next(), TextData.class);\r
+ }\r
+ }\r
+ return textData;\r
+ }\r
\r
//************************** METHODS ***************************************** \r
\r
\r
// ****************** Gathering Event *********************************/\r
\r
+ //country\r
+ @Transient\r
+ public NamedArea getCountry(){\r
+ return (hasGatheringEvent() ? getGatheringEvent(true).getCountry() : null);\r
+ }\r
+ \r
+ public void setCountry(NamedArea country){\r
+ getGatheringEvent(true).setCountry(country);\r
+ }\r
+ \r
+ \r
//Collecting area\r
public void addCollectingArea(NamedArea area) {\r
getGatheringEvent(true).addCollectingArea(area);\r
getGatheringEvent(true).addCollectingArea(area);\r
}\r
}\r
+ @Transient\r
public Set<NamedArea> getCollectingAreas() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getCollectingAreas() : null);\r
}\r
* @see #getAbsoluteElevationError()\r
* @see #getAbsoluteElevationRange()\r
**/\r
+ @Transient\r
public Integer getAbsoluteElevation() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getAbsoluteElevation() : null);\r
}\r
}\r
\r
//absolute elevation error\r
+ @Transient\r
public Integer getAbsoluteElevationError() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getAbsoluteElevationError() : null);\r
}\r
* @see #setAbsoluteElevationRange(Integer, Integer)\r
* @see #getAbsoluteElevationMaximum()\r
*/\r
+ @Transient\r
public Integer getAbsoluteElevationMinimum(){\r
if ( ! hasGatheringEvent() ){\r
return null;\r
* @see #setAbsoluteElevationRange(Integer, Integer)\r
* @see #getAbsoluteElevationMinimum()\r
*/\r
+ @Transient\r
public Integer getAbsoluteElevationMaximum(){\r
if ( ! hasGatheringEvent() ){\r
return null;\r
}\r
\r
//collector\r
+ @Transient\r
public AgentBase getCollector() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getCollector() : null);\r
}\r
}\r
\r
//collecting method\r
+ @Transient\r
public String getCollectingMethod() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getCollectingMethod() : null);\r
}\r
}\r
\r
//distance to ground\r
+ @Transient\r
public Integer getDistanceToGround() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getDistanceToGround() : null);\r
}\r
}\r
\r
//distance to water surface\r
+ @Transient\r
public Integer getDistanceToWaterSurface() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getDistanceToWaterSurface() : null);\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
+ * 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
* @param includeEmptySeconds\r
* @param includeReferenceSystem\r
}\r
\r
//gathering event description\r
+ @Transient\r
public String getGatheringEventDescription() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getDescription() : null);\r
}\r
}\r
\r
//gatering period\r
+ @Transient\r
public TimePeriod getGatheringPeriod() {\r
return (hasGatheringEvent() ? getGatheringEvent(true).getTimeperiod() : null);\r
}\r
}\r
\r
//locality\r
+ @Transient\r
public LanguageString getLocality(){\r
return (hasGatheringEvent() ? getGatheringEvent(true).getLocality() : null);\r
}\r
+ /**\r
+ * convienience method for {@link #getLocality()}.{@link LanguageString#getText() getText()}\r
+ * @return\r
+ */\r
+ @Transient\r
public String getLocalityText(){\r
LanguageString locality = getLocality();\r
if(locality != null){\r
}\r
return null;\r
}\r
+ /**\r
+ * convienience method for {@link #getLocality()}.{@link LanguageString#getLanguage() getLanguage()}\r
+ * @return\r
+ */\r
+ @Transient\r
public Language getLocalityLanguage(){\r
LanguageString locality = getLocality();\r
if(locality != null){\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
\r
//ecology\r
+ @Transient\r
public String getEcology(){\r
return getEcology(Language.DEFAULT());\r
}\r
// LanguageString languageString = getEcologyAll().getPreferredLanguageString(languages);\r
// return languageString.getText();\r
// }\r
+ /**\r
+ * Returns a copy of the multilanguage text holding the ecology data.\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(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
if (ecologyText == null){\r
ecology.removeText(language);\r
}else{\r
- ecology.putText(ecologyText, language);\r
+ ecology.putText(language, ecologyText);\r
}\r
}\r
public void removeEcology(Language language){\r
\r
\r
//plant description\r
+ @Transient\r
public String getPlantDescription(){\r
return getPlantDescription(null);\r
}\r
// LanguageString languageString = getPlantDescriptionAll().getPreferredLanguageString(languages);\r
// return languageString.getText();\r
// }\r
+ /**\r
+ * Returns a copy of the multilanguage text holding the description data.\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(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
if (plantDescriptionText == null){\r
plantDescription.removeText(language);\r
}else{\r
- plantDescription.putText(plantDescriptionText, language);\r
+ plantDescription.putText(language, plantDescriptionText);\r
}\r
}\r
public void removePlantDescription(Language language){\r
setPlantDescription(null, language);\r
}\r
\r
-\r
- \r
//field object definition\r
public void addFieldObjectDefinition(String text, Language language) {\r
getFieldObservation(true).addDefinition(text, language);\r
}\r
+ @Transient\r
public Map<Language, LanguageString> getFieldObjectDefinition() {\r
if (! hasFieldObservation()){\r
return new HashMap<Language, LanguageString>();\r
}\r
}\r
\r
+ public void setFieldObjectImageGallery(SpecimenDescription imageGallery) throws DerivedUnitFacadeNotSupportedException{\r
+ SpecimenDescription existingGallery = getFieldObjectImageGallery(false);\r
+ \r
+ //test attached specimens contain this.derivedUnit\r
+ SpecimenOrObservationBase<?> facadeFieldObservation = innerFieldObservation();\r
+ testSpecimenInImageGallery(imageGallery, facadeFieldObservation);\r
+ \r
+ if (existingGallery != null){\r
+ if (existingGallery != imageGallery){\r
+ throw new DerivedUnitFacadeNotSupportedException("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
/**\r
+ * Returns the field object image gallery. If no such image gallery exists and\r
+ * createIfNotExists is true an new one is created. Otherwise null is returned.\r
* @param createIfNotExists\r
* @return\r
*/\r
* Returns the media for the field object.<BR>\r
* @return\r
*/\r
+ @Transient\r
public List<Media> getFieldObjectMedia() {\r
try {\r
List<Media> result = getMedia(getFieldObservation(false), false);\r
}\r
\r
//field number\r
+ @Transient\r
public String getFieldNumber() {\r
if (! hasFieldObservation()){\r
return null;\r
getFieldObservation(true).setFieldNumber(fieldNumber);\r
}\r
\r
+ //primary collector\r
+ @Transient\r
+ public Person getPrimaryCollector() {\r
+ if (! hasFieldObservation()){\r
+ return null;\r
+ }else{\r
+ return getFieldObservation(true).getPrimaryCollector();\r
+ }\r
+ }\r
+ public void setPrimaryCollector(Person primaryCollector) {\r
+ getFieldObservation(true).setPrimaryCollector(primaryCollector);\r
+ }\r
+ \r
+ \r
\r
//field notes\r
+ @Transient\r
public String getFieldNotes() {\r
if (! hasFieldObservation()){\r
return null;\r
\r
\r
//individual counts\r
+ @Transient\r
public Integer getIndividualCount() {\r
return (hasFieldObservation()? getFieldObservation(true).getIndividualCount() : null );\r
}\r
}\r
\r
//life stage\r
+ @Transient\r
public Stage getLifeStage() {\r
return (hasFieldObservation()? getFieldObservation(true).getLifeStage() : null );\r
}\r
}\r
\r
//sex\r
+ @Transient\r
public Sex getSex() {\r
return (hasFieldObservation()? getFieldObservation(true).getSex() : null );\r
}\r
* Returns the field observation as an object.\r
* @return\r
*/\r
- public FieldObservation getFieldObservation(){\r
+ public FieldObservation innerFieldObservation(){\r
return getFieldObservation(false);\r
}\r
\r
public FieldObservation getFieldObservation(boolean createIfNotExists){\r
if (fieldObservation == null && createIfNotExists){\r
fieldObservation = FieldObservation.NewInstance();\r
+ fieldObservation.addPropertyChangeListener(getNewEventPropagationListener());\r
DerivationEvent derivationEvent = getDerivationEvent(true);\r
derivationEvent.addOriginal(fieldObservation);\r
}\r
\r
\r
\r
+\r
+ \r
//****************** Specimen ************************************************** \r
\r
//Definition\r
public void addDerivedUnitDefinition(String text, Language language) {\r
derivedUnit.addDefinition(text, language);\r
}\r
+ @Transient\r
public Map<Language, LanguageString> getDerivedUnitDefinitions(){\r
return this.derivedUnit.getDefinition();\r
}\r
public void addDetermination(DeterminationEvent determination) {\r
derivedUnit.addDetermination(determination);\r
}\r
+ @Transient\r
public Set<DeterminationEvent> getDeterminations() {\r
return derivedUnit.getDeterminations();\r
}\r
public SpecimenDescription getDerivedUnitImageGallery(boolean createIfNotExists){\r
TextData textData;\r
try {\r
- textData = inititialzeTextDataWithSupportTest(Feature.IMAGE(), derivedUnit, createIfNotExists, true);\r
+ textData = inititializeTextDataWithSupportTest(Feature.IMAGE(), derivedUnit, createIfNotExists, true);\r
} catch (DerivedUnitFacadeNotSupportedException e) {\r
throw new IllegalStateException(notSupportMessage, e);\r
}\r
return null;\r
}\r
}\r
+ public void setDerivedUnitImageGallery(SpecimenDescription imageGallery) throws DerivedUnitFacadeNotSupportedException{\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("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) throws DerivedUnitFacadeNotSupportedException {\r
+ Set<SpecimenOrObservationBase> imageGallerySpecimens = imageGallery.getDescribedSpecimenOrObservations();\r
+ if (imageGallerySpecimens.size() < 1){\r
+ throw new DerivedUnitFacadeNotSupportedException("Image Gallery has no Specimen attached. Please attache according specimen or field observation.");\r
+ }\r
+ if (! imageGallerySpecimens.contains(specimen)){\r
+ throw new DerivedUnitFacadeNotSupportedException("Image Gallery has not the facade's field object attached. Please add field object first to image gallery specimenOrObservation list.");\r
+ }\r
+ }\r
\r
/**\r
* Returns the media for the specimen.<BR>\r
* @return\r
*/\r
+ @Transient\r
public List<Media> getDerivedUnitMedia() {\r
try {\r
List<Media> result = getMedia(derivedUnit, false);\r
\r
\r
//Accession Number\r
+ @Transient\r
public String getAccessionNumber() {\r
return derivedUnit.getAccessionNumber();\r
}\r
derivedUnit.setAccessionNumber(accessionNumber);\r
}\r
\r
- //Catalog Number\r
+ @Transient\r
public String getCatalogNumber() {\r
return derivedUnit.getCatalogNumber();\r
}\r
derivedUnit.setCatalogNumber(catalogNumber);\r
}\r
\r
+ @Transient\r
+ public String getBarcode() {\r
+ return derivedUnit.getBarcode();\r
+ }\r
+ public void setBarcode(String barcode) {\r
+ derivedUnit.setBarcode(barcode);\r
+ }\r
+\r
+ \r
//Preservation Method\r
\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
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()){\r
+ throw new MethodNotSupportedByDerivedUnitTypeException("A preservation method is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ }else{\r
+ return null;\r
+ }\r
}\r
}\r
/**\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
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()){\r
+ throw new MethodNotSupportedByDerivedUnitTypeException("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
+ @Transient\r
public TaxonNameBase getStoredUnder() {\r
return derivedUnit.getStoredUnder();\r
}\r
}\r
\r
//colletors number\r
+ @Transient\r
public String getCollectorsNumber() {\r
return derivedUnit.getCollectorsNumber();\r
}\r
}\r
return this.derivedUnit.getTitleCache();\r
}\r
+ public boolean isProtectedTitleCache(){\r
+ return derivedUnit.isProtectedTitleCache();\r
+ }\r
public void setTitleCache(String titleCache, boolean isProtected) {\r
this.derivedUnit.setTitleCache(titleCache, isProtected);\r
}\r
* Returns the derived unit itself.\r
* @return the derived unit\r
*/\r
- public DerivedUnitBase getDerivedUnit() {\r
+ public DerivedUnitBase innerDerivedUnit() {\r
return this.derivedUnit;\r
}\r
\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
+ @Transient\r
+ public String getExsiccatum() throws MethodNotSupportedByDerivedUnitTypeException {\r
+ if (derivedUnit.isInstanceOf(Specimen.class)){\r
+ return CdmBase.deproxy(derivedUnit, Specimen.class).getExsiccatum();\r
+ }else{\r
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()){\r
+ throw new MethodNotSupportedByDerivedUnitTypeException("An exsiccatum is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ }else{\r
+ return null;\r
+ }\r
+ }\r
}\r
\r
- public String setExsiccatum() throws MethodNotSupportedException{\r
- throw new MethodNotSupportedException("Exsiccatum method not yet supported. Needs model change");\r
+ public void setExsiccatum(String exsiccatum) throws Exception{\r
+ if (derivedUnit.isInstanceOf(Specimen.class)){\r
+ CdmBase.deproxy(derivedUnit, Specimen.class).setExsiccatum(exsiccatum);\r
+ }else{\r
+ if (this.config.isThrowExceptionForNonSpecimenPreservationMethodRequest()){\r
+ throw new MethodNotSupportedByDerivedUnitTypeException("An exsiccatum is only available in derived units of type 'Specimen' or 'Fossil'");\r
+ }else{\r
+ return;\r
+ }\r
+ }\r
}\r
\r
\r
* @param originalNameString\r
* @return\r
*/\r
- public IdentifiableSource addSource(ReferenceBase reference, String microReference, String originalNameString){\r
+ public IdentifiableSource addSource(Reference reference, String microReference, String originalNameString){\r
IdentifiableSource source = IdentifiableSource.NewInstance(reference, microReference);\r
source.setOriginalNameString(originalNameString);\r
derivedUnit.addSource(source);\r
return source;\r
}\r
- \r
+\r
+ @Transient\r
public Set<IdentifiableSource> getSources(){\r
return derivedUnit.getSources();\r
}\r
/**\r
* @return the collection\r
*/\r
+ @Transient\r
public Collection getCollection() {\r
return derivedUnit.getCollection();\r
}\r
derivedUnit.setCollection(collection);\r
}\r
\r
+ //annotation \r
+ public void addAnnotation(Annotation annotation){\r
+ this.derivedUnit.addAnnotation(annotation);\r
+ }\r
+\r
+ @Transient\r
+ public void getAnnotations(){\r
+ this.derivedUnit.getAnnotations();\r
+ }\r
\r
+ public void removeAnnotation(Annotation annotation){\r
+ this.derivedUnit.removeAnnotation(annotation);\r
+ }\r
+ \r
+ \r
+// ******************************* Events *********************************************\r
+ \r
+ /**\r
+ * @return\r
+ */\r
+ private PropertyChangeListener getNewEventPropagationListener() {\r
+ PropertyChangeListener listener = new PropertyChangeListener(){\r
+ @Override\r
+ public void propertyChange(PropertyChangeEvent event) {\r
+ derivedUnit.firePropertyChange(event);\r
+ }\r
+ \r
+ };\r
+ return listener;\r
+ }\r
\r
+ \r
\r
\r
//**************** Other Collections *************************************************** \r
//TODO check derivedUnitType\r
getDerivationEvent(true).addDerivative(duplicateSpecimen); \r
}\r
+ \r
+ @Transient\r
public Set<Specimen> getDuplicates(){\r
Set<Specimen> result = new HashSet<Specimen>();\r
if (hasDerivationEvent()){\r