Skip to content

Commit 73dccbf

Browse files
committed
Improve contact parsing in the EmlImportService and added tests for this and the IPTService (fix for #259)
1 parent dbd6bb7 commit 73dccbf

File tree

5 files changed

+810
-57
lines changed

5 files changed

+810
-57
lines changed

build.gradle

+8-2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ dependencies {
127127
testImplementation "org.grails:grails-gorm-testing-support"
128128
testImplementation "org.mockito:mockito-core"
129129
testImplementation "org.grails:grails-web-testing-support"
130+
testImplementation "org.grails:grails-testing-support"
131+
testImplementation "org.spockframework:spock-core"
130132
// testImplementation "org.grails.plugins:geb"
131133
// testImplementation "org.seleniumhq.selenium:selenium-remote-driver:$seleniumVersion"
132134
// testImplementation "org.seleniumhq.selenium:selenium-api:$seleniumVersion"
@@ -175,6 +177,10 @@ assets {
175177
}
176178

177179
test {
178-
testLogging.showStandardStreams = true
180+
useJUnitPlatform()
181+
include '**/*Spec.*'
182+
testLogging {
183+
events "PASSED", "FAILED", "SKIPPED"
184+
showStandardStreams = true
185+
}
179186
}
180-

grails-app/services/au/org/ala/collectory/EmlImportService.groovy

+57-55
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@ class EmlImportService {
112112
* @param connParams
113113
* @return
114114
*/
115-
def extractContactsFromEml(eml, dataResource){
116-
115+
def extractContactsFromEml(eml, dataResource) {
117116
def contacts = []
118117
def primaryContacts = []
118+
def processedContacts = []
119119

120120
emlFields.each { name, accessor ->
121121
def val = accessor(eml)
@@ -124,45 +124,45 @@ class EmlImportService {
124124
}
125125
}
126126

127-
//add contacts...
128-
if (eml.dataset.creator){
129-
eml.dataset.creator.each {
130-
def contact = addOrUpdateContact(it)
131-
if (contact){
127+
def addUniqueContact = { provider ->
128+
def providerEmail = provider.electronicMailAddress?.text()?.trim()
129+
def providerName = "${provider.individualName?.givenName?.text()?.trim()}_${provider.individualName?.surName?.text()?.trim()}"
130+
def providerOrg = provider.organizationName?.text()?.trim()
131+
def providerPosition = provider.positionName?.text()?.trim()
132+
133+
def uniqueKey = providerEmail ?: providerName ?: providerOrg ?: providerPosition
134+
if (uniqueKey && !processedContacts.contains(uniqueKey)) {
135+
def contact = addOrUpdateContact(provider)
136+
if (contact) {
132137
contacts << contact
138+
processedContacts << uniqueKey
139+
return contact
133140
}
134141
}
135142
}
136143

137-
if (eml.dataset.metadataProvider
138-
&& eml.dataset.metadataProvider.electronicMailAddress != eml.dataset.creator.electronicMailAddress){
144+
// EML Schema
145+
// https://eml.ecoinformatics.org/images/eml-party.png
139146

140-
eml.dataset.metadataProvider.each {
141-
def contact = addOrUpdateContact(it)
142-
if (contact){
143-
contacts << contact
144-
}
145-
}
147+
if (eml.dataset.creator) {
148+
eml.dataset.creator.each { addUniqueContact(it) }
146149
}
147150

148-
// Add additional contacts
149-
if (eml.dataset.contact){
151+
if (eml.dataset.contact) {
150152
eml.dataset.contact.each {
151-
def contact = addOrUpdateContact(it)
152-
if (contact){
153-
contacts << contact
153+
def contact = addUniqueContact(it)
154+
if (contact) {
154155
primaryContacts << contact
155156
}
156157
}
157158
}
158159

159-
if (eml.dataset.associatedParty){
160-
eml.dataset.associatedParty.each {
161-
def contact = addOrUpdateContact(it)
162-
if (contact){
163-
contacts << contact
164-
}
165-
}
160+
if (eml.dataset.metadataProvider) {
161+
eml.dataset.metadataProvider.each { addUniqueContact(it) }
162+
}
163+
164+
if (eml.dataset.associatedParty) {
165+
eml.dataset.associatedParty.each { addUniqueContact(it) }
166166
}
167167

168168
[contacts: contacts, primaryContacts: primaryContacts]
@@ -173,42 +173,44 @@ class EmlImportService {
173173
if (emlElement.electronicMailAddress && !emlElement.electronicMailAddress.isEmpty()) {
174174
String email = emlElement.electronicMailAddress.text().trim()
175175
contact = Contact.findByEmail(email)
176-
} else if (emlElement.individualName.givenName && emlElement.individualName.surName) {
177-
contact = Contact.findByFirstNameAndLastName(emlElement.individualName.givenName, emlElement.individualName.surName)
178-
} else if (emlElement.individualName.surName) {
179-
// surName is mandatory
180-
contact = Contact.findByLastName(emlElement.individualName.surName)
176+
} else if (emlElement.individualName?.givenName && emlElement.individualName?.surName) {
177+
contact = Contact.findByFirstNameAndLastName(
178+
emlElement.individualName.givenName.text()?.trim(),
179+
emlElement.individualName.surName.text()?.trim()
180+
)
181+
} else if (emlElement.individualName?.surName) {
182+
contact = Contact.findByLastName(emlElement.individualName.surName.text()?.trim())
183+
} else if (emlElement.organizationName) {
184+
contact = Contact.findByFirstName(emlElement.organizationName.text()?.trim())
185+
} else if (emlElement.positionName) {
186+
contact = Contact.findByFirstName(emlElement.positionName.text()?.trim())
181187
}
182188

183-
// Create the contact if it doesn't exist and it's a individualName with email or surName
184-
// to prevent empty contacts (e.g. with emlElement.organizationName only)
185189
boolean hasEmail = emlElement?.electronicMailAddress?.text()?.trim()?.isEmpty() == false
186190
boolean hasName = emlElement?.individualName?.surName?.text()?.trim()?.isEmpty() == false
191+
boolean hasOrg = emlElement?.organizationName?.text()?.trim()?.isEmpty() == false
192+
boolean hasPosition = emlElement?.positionName?.text()?.trim()?.isEmpty() == false
187193

188-
if (!contact && (hasEmail || hasName)) {
194+
if (!contact && (hasEmail || hasName || hasOrg || hasPosition)) {
189195
contact = new Contact()
190-
} else {
191-
return null
192-
}
193-
194-
// Update the contact details
195-
contact.firstName = emlElement.individualName.givenName
196-
contact.lastName = emlElement.individualName.surName
197-
// some email has leading/trailing spaces causing the email constrain regexp to fail, lets trim
198-
contact.email = emlElement.electronicMailAddress.text().trim()
199-
contact.setUserLastModified(collectoryAuthService.username())
200-
Contact.withTransaction {
201-
if (contact.validate()) {
202-
contact.save(flush: true, failOnError: true)
203-
return contact
204-
} else {
205-
contact.errors.each {
206-
log.error("Problem creating contact: " + it)
196+
// For now we are just going to set the first name to the organization name
197+
contact.firstName = emlElement.individualName?.givenName?.text()?.trim()
198+
if (hasOrg)
199+
contact.firstName = emlElement.organizationName?.text()?.trim()
200+
if (hasPosition)
201+
contact.firstName = emlElement.positionName?.text()?.trim()
202+
contact.lastName = emlElement.individualName?.surName?.text()?.trim()
203+
contact.email = emlElement.electronicMailAddress?.text()?.trim()
204+
contact.setUserLastModified(collectoryAuthService.username())
205+
Contact.withTransaction {
206+
if (contact.validate()) {
207+
contact.save(flush: true, failOnError: true)
208+
} else {
209+
log.error("Validation errors creating contact: ${contact.errors}")
210+
return null
207211
}
208-
return null
209212
}
210213
}
211-
212-
contact
214+
return contact
213215
}
214216
}

0 commit comments

Comments
 (0)