Search in sources :

Example 1 with TaxonomicCoverage

use of org.gbif.metadata.eml.TaxonomicCoverage in project ipt by gbif.

the class ResourceAction method constructOrganizedTaxonomicCoverages.

/**
 * Takes a list of the resource's TaxonomicCoverages, and for each one, creates a new OrganizedTaxonomicCoverage
 * that gets added to the class' list of OrganizedTaxonomicCoverage.
 *
 * @param coverages list of resource's TaxonomicCoverage
 */
List<OrganizedTaxonomicCoverage> constructOrganizedTaxonomicCoverages(List<TaxonomicCoverage> coverages) {
    List<OrganizedTaxonomicCoverage> organizedTaxonomicCoverages = new ArrayList<>();
    for (TaxonomicCoverage coverage : coverages) {
        OrganizedTaxonomicCoverage organizedCoverage = new OrganizedTaxonomicCoverage();
        organizedCoverage.setDescription(coverage.getDescription());
        organizedCoverage.setKeywords(setOrganizedTaxonomicKeywords(coverage.getTaxonKeywords()));
        organizedTaxonomicCoverages.add(organizedCoverage);
    }
    return organizedTaxonomicCoverages;
}
Also used : ArrayList(java.util.ArrayList) TaxonomicCoverage(org.gbif.metadata.eml.TaxonomicCoverage)

Example 2 with TaxonomicCoverage

use of org.gbif.metadata.eml.TaxonomicCoverage in project ipt by gbif.

the class ResourceActionTest method setup.

@BeforeEach
public void setup() throws IOException, TemplateException {
    SimpleTextProvider textProvider = new SimpleTextProvider();
    LocaleProviderFactory localeProviderFactory = new DefaultLocaleProviderFactory();
    AppConfig mockCfg = mock(AppConfig.class);
    RegistrationManager mockRegistrationManager = mock(RegistrationManager.class);
    ResourceManager mockResourceManager = mock(ResourceManager.class);
    VocabulariesManager mockVocabManager = mock(VocabulariesManager.class);
    DataDir mockDataDir = mock(DataDir.class);
    Container container = mock(Container.class);
    // mock: vocabManager.getI18nVocab(Constants.VOCAB_URI_RANKS, Locale.getDefault().getLanguage(), false);
    Map<String, String> ranks = new LinkedHashMap<>();
    ranks.put("kingdom", "http://rs.gbif.org/vocabulary/gbif/rank/kingdom");
    ranks.put("Class", "http://rs.gbif.org/vocabulary/gbif/rank/class");
    when(mockVocabManager.getI18nVocab(anyString(), anyString(), anyBoolean())).thenReturn(ranks);
    // setup Resource with TaxonomicCoverage with 3 TaxonKeyword
    resource = new Resource();
    resource.setShortname(RESOURCE_SHORT_NAME);
    resource.setEmlVersion(LATEST_RESOURCE_VERSION);
    // setup manager as resource creator
    MANAGER = new User();
    MANAGER.setEmail("jc@gbif.org");
    MANAGER.setLastname("Costa");
    MANAGER.setFirstname("Jose");
    MANAGER.setRole(User.Role.Manager);
    resource.setCreator(MANAGER);
    // add three published versions to version history, all published by manager, some private, other public
    VersionHistory v1 = new VersionHistory(RESOURCE_VERSION_ONE, new Date(), PublicationStatus.PRIVATE);
    resource.addVersionHistory(v1);
    VersionHistory v2 = new VersionHistory(RESOURCE_VERSION_TWO, new Date(), PublicationStatus.PUBLIC);
    resource.addVersionHistory(v2);
    VersionHistory v3 = new VersionHistory(LATEST_RESOURCE_VERSION, new Date(), PublicationStatus.PRIVATE);
    resource.addVersionHistory(v3);
    assertEquals(3, resource.getVersionHistory().size());
    TaxonomicCoverage coverage1 = new TaxonomicCoverage();
    coverage1.setDescription("Description1");
    TaxonKeyword keyword1 = new TaxonKeyword();
    keyword1.setRank("Kingdom");
    keyword1.setCommonName("Plants");
    keyword1.setScientificName("Plantae");
    TaxonKeyword keyword2 = new TaxonKeyword();
    keyword2.setRank("Class");
    keyword2.setScientificName("Equisetopsida");
    TaxonKeyword keyword3 = new TaxonKeyword();
    keyword3.setCommonName("Sedges");
    List<TaxonKeyword> keywordList = new ArrayList<>();
    keywordList.add(keyword1);
    keywordList.add(keyword2);
    keywordList.add(keyword3);
    coverage1.setTaxonKeywords(keywordList);
    List<TaxonomicCoverage> coverages = new ArrayList<>();
    coverages.add(coverage1);
    resource.getEml().setTaxonomicCoverages(coverages);
    // mock returning EML file, with actual resource metadata
    File emlFile = File.createTempFile("eml-3.0.xml", ".xml");
    EmlWriter.writeEmlFile(emlFile, resource.getEml());
    when(mockDataDir.resourceEmlFile(anyString(), any(BigDecimal.class))).thenReturn(emlFile);
    // mock returning RTF file, with empty content
    File rtfFile = File.createTempFile(RESOURCE_SHORT_NAME + "-3.0", ".rtf");
    when(mockDataDir.resourceRtfFile(anyString(), any(BigDecimal.class))).thenReturn(rtfFile);
    // mock returning DwC-A file, with file that doesn't exist. This means the resource is metadata-only
    File nonExistingDwca = new File("dwca", ".zip");
    assertFalse(nonExistingDwca.exists());
    when(mockDataDir.resourceDwcaFile(anyString(), any(BigDecimal.class))).thenReturn(nonExistingDwca);
    // mock a locale provider
    when(container.getInstance(LocaleProviderFactory.class)).thenReturn(localeProviderFactory);
    action = new ResourceAction(textProvider, mockCfg, mockRegistrationManager, mockResourceManager, mockVocabManager, mockDataDir, mock(ExtensionManager.class));
    action.setResource(resource);
    action.setContainer(container);
}
Also used : AppConfig(org.gbif.ipt.config.AppConfig) RegistrationManager(org.gbif.ipt.service.admin.RegistrationManager) User(org.gbif.ipt.model.User) TaxonKeyword(org.gbif.metadata.eml.TaxonKeyword) Resource(org.gbif.ipt.model.Resource) ArrayList(java.util.ArrayList) ResourceManager(org.gbif.ipt.service.manage.ResourceManager) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) VocabulariesManager(org.gbif.ipt.service.admin.VocabulariesManager) VersionHistory(org.gbif.ipt.model.VersionHistory) Date(java.util.Date) BigDecimal(java.math.BigDecimal) LinkedHashMap(java.util.LinkedHashMap) Container(com.opensymphony.xwork2.inject.Container) SimpleTextProvider(org.gbif.ipt.struts2.SimpleTextProvider) TaxonomicCoverage(org.gbif.metadata.eml.TaxonomicCoverage) DefaultLocaleProviderFactory(com.opensymphony.xwork2.DefaultLocaleProviderFactory) LocaleProviderFactory(com.opensymphony.xwork2.LocaleProviderFactory) DefaultLocaleProviderFactory(com.opensymphony.xwork2.DefaultLocaleProviderFactory) File(java.io.File) DataDir(org.gbif.ipt.config.DataDir) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 3 with TaxonomicCoverage

use of org.gbif.metadata.eml.TaxonomicCoverage in project ipt by gbif.

the class Eml2Rtf method addTaxonomicCoverages.

/**
 * Add taxonomic coverages, writing in this order: description, ranks, then common names.
 *
 * @param doc Document
 * @param eml EML object
 * @throws DocumentException if an error occurred adding to the Document
 */
private void addTaxonomicCoverages(Document doc, Eml eml) throws DocumentException {
    // proceed, provided there is at least 1 Taxonomic Coverage to iterate over
    if (exists(eml.getTaxonomicCoverages()) && !eml.getTaxonomicCoverages().isEmpty()) {
        // begin new paragraph
        Paragraph p = new Paragraph();
        p.setAlignment(Element.ALIGN_JUSTIFIED);
        p.setFont(font);
        boolean firstTaxon = true;
        for (TaxonomicCoverage taxcoverage : eml.getTaxonomicCoverages()) {
            if (!firstTaxon) {
                p.add(Chunk.NEWLINE);
            }
            firstTaxon = false;
            p.add(new Phrase(getText("rtf.taxcoverage"), fontTitle));
            p.add(Chunk.NEWLINE);
            p.add(Chunk.NEWLINE);
            if (exists(taxcoverage.getDescription())) {
                p.add(new Phrase(getText("rtf.taxcoverage.description") + ": ", fontTitle));
                p.add(taxcoverage.getDescription().replace("\r\n", "\n"));
                p.add(Chunk.NEWLINE);
            }
            Map<String, String> ranks = vocabManager.getI18nVocab(Constants.VOCAB_URI_RANKS, Locale.getDefault().getLanguage(), false);
            boolean firstRank = true;
            for (String rank : ranks.keySet()) {
                boolean wroteRank = false;
                for (TaxonKeyword keyword : taxcoverage.getTaxonKeywords()) {
                    if (exists(keyword.getRank()) && keyword.getRank().equals(rank)) {
                        if (!wroteRank) {
                            if (firstRank) {
                                p.add(new Phrase(getText("rtf.taxcoverage.rank"), fontTitle));
                            }
                            p.add(Chunk.NEWLINE);
                            p.add(StringUtils.capitalize(rank) + ": ");
                            p.add(keyword.getScientificName());
                            wroteRank = true;
                            firstRank = false;
                        } else {
                            p.add(", " + keyword.getScientificName());
                        }
                    }
                }
            }
            p.add(Chunk.NEWLINE);
            boolean isFirst = true;
            for (TaxonKeyword keyword : taxcoverage.getTaxonKeywords()) {
                if (exists(keyword.getCommonName())) {
                    if (isFirst) {
                        p.add(new Phrase(getText("rtf.taxcoverage.common") + ": ", fontTitle));
                    } else {
                        p.add(", ");
                    }
                    isFirst = false;
                    p.add(keyword.getCommonName());
                }
            }
        }
        p.add(Chunk.NEWLINE);
        doc.add(p);
        p.clear();
    }
}
Also used : TaxonKeyword(org.gbif.metadata.eml.TaxonKeyword) TaxonomicCoverage(org.gbif.metadata.eml.TaxonomicCoverage) Phrase(com.lowagie.text.Phrase) Paragraph(com.lowagie.text.Paragraph)

Example 4 with TaxonomicCoverage

use of org.gbif.metadata.eml.TaxonomicCoverage in project ipt by gbif.

the class EmlValidator method validate.

/**
 * Validate an EML document, optionally only a part of it.
 * </br>
 * For each section, validation only proceeds if at least one field in the section's form has been entered.
 *
 * @param action BaseAction
 * @param resource resource
 * @param section EML document section name
 */
public void validate(BaseAction action, Resource resource, @Nullable MetadataSection section) {
    if (resource != null) {
        Eml eml = (resource.getEml() == null) ? new Eml() : resource.getEml();
        // set default
        if (section == null) {
            section = MetadataSection.BASIC_SECTION;
        }
        switch(section) {
            case BASIC_SECTION:
                // Title - mandatory
                if (StringUtils.isBlank(eml.getTitle())) {
                    action.addFieldError("eml.title", action.getText("validation.required", new String[] { action.getText("eml.title") }));
                }
                // Title - not a short name of the resource
                if (resource.getShortname() != null && resource.getShortname().equals(eml.getTitle())) {
                    action.addActionWarning(action.getText("eml.title.shortname.match"));
                }
                // description - mandatory and greater than 5 chars
                if (eml.getDescription().isEmpty()) {
                    action.addActionError(action.getText("validation.required", new String[] { action.getText("eml.description") }));
                } else {
                    // ensure each description is longer than min length
                    int index = 0;
                    for (String d : eml.getDescription()) {
                        if (!exists(d, 5)) {
                            action.addFieldError("eml.description[" + index + "]", action.getText("validation.short", new String[] { action.getText("eml.description"), "5" }));
                        }
                        index++;
                    }
                }
                // intellectual rights - mandatory
                if (StringUtils.isBlank(eml.getIntellectualRights())) {
                    action.addFieldError("eml.intellectualRights.license", action.getText("validation.required", new String[] { action.getText("eml.intellectualRights.license") }));
                }
                // publishing organisation - mandatory
                if (resource.getOrganisation() == null) {
                    action.addFieldError("id", action.getText("validation.required", new String[] { action.getText("portal.home.organisation") }));
                } else if (regManager.get(resource.getOrganisation().getKey()) == null) {
                    action.addFieldError("id", action.getText("eml.publishingOrganisation.notFound", new String[] { resource.getOrganisation().getKey().toString() }));
                }
                // type - mandatory
                if (StringUtils.isBlank(resource.getCoreType())) {
                    action.addFieldError("resource.coreType", action.getText("validation.required", new String[] { action.getText("resource.coreType") }));
                }
                // metadata language - mandatory (defaults to 3 letter ISO code for English)
                if (StringUtils.isBlank(eml.getMetadataLanguage())) {
                    action.addActionWarning(action.getText("eml.metadataLanguage.default"));
                    eml.setMetadataLanguage(Language.ENGLISH.getIso3LetterCode());
                }
                // data language - mandatory unless resource is metadata-only (defaults to English)
                if (StringUtils.isBlank(eml.getLanguage()) && resource.getCoreType() != null && !resource.getCoreType().equalsIgnoreCase(Resource.CoreRowType.METADATA.toString())) {
                    action.addActionWarning(action.getText("eml.language.default"));
                    eml.setLanguage(Language.ENGLISH.getIso3LetterCode());
                }
                // update frequency - mandatory (defaults to Unknown)
                if (eml.getUpdateFrequency() == null) {
                    if (resource.getUpdateFrequency() != null) {
                        eml.setUpdateFrequency(resource.getUpdateFrequency().getIdentifier());
                        action.addActionWarning(action.getText("eml.updateFrequency.default.interval", new String[] { resource.getUpdateFrequency().getIdentifier() }));
                    } else {
                        action.addActionWarning(action.getText("eml.updateFrequency.default"));
                        eml.setUpdateFrequency(MaintenanceUpdateFrequency.UNKOWN.getIdentifier());
                    }
                }
                // Contacts list: at least one field has to have had data entered into it to qualify for validation
                if (isAgentsListEmpty(eml.getContacts())) {
                    action.addActionError(action.getText("eml.contact.required"));
                } else {
                    for (int index = 0; index < eml.getContacts().size(); index++) {
                        Agent c = eml.getContacts().get(index);
                        // firstName - optional. But if firstName exists, lastName have to exist
                        if (exists(c.getFirstName()) && !exists(c.getLastName())) {
                            action.addFieldError("eml.contacts[" + index + "].lastName", action.getText("validation.firstname.lastname"));
                        }
                        // directory and personnel id both required (if either is supplied)
                        if (!c.getUserIds().isEmpty()) {
                            if (exists(c.getUserIds().get(0).getDirectory()) && !exists(c.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.contacts[" + index + "].userIds[0].identifier", action.getText("validation.personnel"));
                            } else if (!exists(c.getUserIds().get(0).getDirectory()) && exists(c.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.contacts[" + index + "].userIds[0].directory", action.getText("validation.directory"));
                            }
                        }
                        // At least one of organisation, position, or a lastName have to exist
                        if (!exists(c.getOrganisation()) && !exists(c.getLastName()) && !exists(c.getPosition())) {
                            action.addActionError(action.getText("validation.lastname.organisation.position"));
                            action.addFieldError("eml.contacts[" + index + "].organisation", action.getText("validation.required", new String[] { action.getText("eml.contact.organisation") }));
                            action.addFieldError("eml.contacts[" + index + "].lastName", action.getText("validation.required", new String[] { action.getText("eml.contact.lastName") }));
                            action.addFieldError("eml.contacts[" + index + "].position", action.getText("validation.required", new String[] { action.getText("eml.contact.position") }));
                        }
                        /* email is optional. But if it exists, should be a valid email address */
                        if (exists(c.getEmail()) && !isValidEmail(c.getEmail())) {
                            action.addFieldError("eml.contacts[" + index + "].email", action.getText("validation.invalid", new String[] { action.getText("eml.contact.email") }));
                        }
                        /* phone is optional. But if it exists, should match the pattern */
                        if (exists(c.getPhone()) && !isValidPhoneNumber(c.getPhone())) {
                            action.addFieldError("eml.contacts[" + index + "].phone", action.getText("validation.invalid", new String[] { action.getText("eml.contact.phone") }));
                        }
                        /* Validate the homepage URL from each contact */
                        if (c.getHomepage() != null) {
                            if (formatURL(c.getHomepage()) == null) {
                                action.addFieldError("eml.contacts[" + index + "].homepage", action.getText("validation.invalid", new String[] { action.getText("eml.contact.homepage") }));
                            } else {
                                c.setHomepage(formatURL(c.getHomepage()));
                            }
                        }
                    }
                }
                // at least one field has to have had data entered into it to qualify for validation
                if (isAgentsListEmpty(eml.getCreators())) {
                    action.addActionError(action.getText("eml.resourceCreator.required"));
                } else {
                    for (int index = 0; index < eml.getCreators().size(); index++) {
                        Agent c = eml.getCreators().get(index);
                        // firstName - optional. But if firstName exists, lastName have to exist
                        if (exists(c.getFirstName()) && !exists(c.getLastName())) {
                            action.addFieldError("eml.creators[" + index + "].lastName", action.getText("validation.firstname.lastname"));
                        }
                        // directory and personnel id both required (if either is supplied)
                        if (!c.getUserIds().isEmpty()) {
                            if (exists(c.getUserIds().get(0).getDirectory()) && !exists(c.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.creators[" + index + "].userIds[0].identifier", action.getText("validation.personnel"));
                            } else if (!exists(c.getUserIds().get(0).getDirectory()) && exists(c.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.creators[" + index + "].userIds[0].directory", action.getText("validation.directory"));
                            }
                        }
                        // At least one of organisation, position, or a lastName have to exist
                        if (!exists(c.getOrganisation()) && !exists(c.getLastName()) && !exists(c.getPosition())) {
                            action.addActionError(action.getText("validation.lastname.organisation.position"));
                            action.addFieldError("eml.creators[" + index + "].organisation", action.getText("validation.required", new String[] { action.getText("eml.resourceCreator.organisation") }));
                            action.addFieldError("eml.creators[" + index + "].lastName", action.getText("validation.required", new String[] { action.getText("eml.resourceCreator.lastName") }));
                            action.addFieldError("eml.creators[" + index + "].position", action.getText("validation.required", new String[] { action.getText("eml.resourceCreator.position") }));
                        }
                        /* email is optional. But if it exists, should be a valid email address */
                        if (exists(c.getEmail()) && !isValidEmail(c.getEmail())) {
                            action.addFieldError("eml.creators[" + index + "].email", action.getText("validation.invalid", new String[] { action.getText("eml.resourceCreator.email") }));
                        }
                        /* phone is optional. But if it exists, should match the pattern */
                        if (exists(c.getPhone()) && !isValidPhoneNumber(c.getPhone())) {
                            action.addFieldError("eml.creators[" + index + "].phone", action.getText("validation.invalid", new String[] { action.getText("eml.resourceCreator.phone") }));
                        }
                        /* Validate the homepage URL from each contact */
                        if (c.getHomepage() != null) {
                            if (formatURL(c.getHomepage()) == null) {
                                action.addFieldError("eml.creators[" + index + "].homepage", action.getText("validation.invalid", new String[] { action.getText("eml.resourceCreator.homepage") }));
                            } else {
                                c.setHomepage(formatURL(c.getHomepage()));
                            }
                        }
                    }
                }
                // MetadataProviders list: at least one field has to have had data entered into it to qualify for validation
                if (isAgentsListEmpty(eml.getMetadataProviders())) {
                    action.addActionError(action.getText("eml.metadataProvider.required"));
                } else {
                    for (int index = 0; index < eml.getMetadataProviders().size(); index++) {
                        Agent c = eml.getMetadataProviders().get(index);
                        // firstName - optional. But if firstName exists, lastName have to exist
                        if (exists(c.getFirstName()) && !exists(c.getLastName())) {
                            action.addFieldError("eml.metadataProviders[" + index + "].lastName", action.getText("validation.firstname.lastname"));
                        }
                        // directory and personnel id both required (if either is supplied)
                        if (!c.getUserIds().isEmpty()) {
                            if (exists(c.getUserIds().get(0).getDirectory()) && !exists(c.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.metadataProviders[" + index + "].userIds[0].identifier", action.getText("validation.personnel"));
                            } else if (!exists(c.getUserIds().get(0).getDirectory()) && exists(c.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.metadataProviders[" + index + "].userIds[0].directory", action.getText("validation.directory"));
                            }
                        }
                        // At least one of organisation, position, or a lastName have to exist
                        if (!exists(c.getOrganisation()) && !exists(c.getLastName()) && !exists(c.getPosition())) {
                            action.addActionError(action.getText("validation.lastname.organisation.position"));
                            action.addFieldError("eml.metadataProviders[" + index + "].organisation", action.getText("validation.required", new String[] { action.getText("eml.metadataProvider.organisation") }));
                            action.addFieldError("eml.metadataProviders[" + index + "].lastName", action.getText("validation.required", new String[] { action.getText("eml.metadataProvider.lastName") }));
                            action.addFieldError("eml.metadataProviders[" + index + "].position", action.getText("validation.required", new String[] { action.getText("eml.metadataProvider.position") }));
                        }
                        /* email is optional. But if it exists, should be a valid email address */
                        if (exists(c.getEmail()) && !isValidEmail(c.getEmail())) {
                            action.addFieldError("eml.metadataProviders[" + index + "].email", action.getText("validation.invalid", new String[] { action.getText("eml.metadataProvider.email") }));
                        }
                        /* phone is optional. But if it exists, should match the pattern */
                        if (exists(c.getPhone()) && !isValidPhoneNumber(c.getPhone())) {
                            action.addFieldError("eml.metadataProviders[" + index + "].phone", action.getText("validation.invalid", new String[] { action.getText("eml.metadataProvider.phone") }));
                        }
                        /* Validate the homepage URL from each contact */
                        if (c.getHomepage() != null) {
                            if (formatURL(c.getHomepage()) == null) {
                                action.addFieldError("eml.metadataProviders[" + index + "].homepage", action.getText("validation.invalid", new String[] { action.getText("eml.metadataProvider.homepage") }));
                            } else {
                                c.setHomepage(formatURL(c.getHomepage()));
                            }
                        }
                    }
                }
                break;
            case GEOGRAPHIC_COVERAGE_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isGeoPageEmpty(eml)) {
                    Double coord = 0.0;
                    for (int index = 0; index < eml.getGeospatialCoverages().size(); index++) {
                        // The Bounding coordinates and description are mandatory.
                        if (!eml.getGeospatialCoverages().isEmpty()) {
                            coord = eml.getGeospatialCoverages().get(index).getBoundingCoordinates().getMin().getLongitude();
                            if (coord == null) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.min.longitude", action.getText("validation.required", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.min.longitude") }));
                            } else if (Double.isNaN(coord)) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.min.longitude", action.getText("validation.invalid", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.min.longitude") }));
                            }
                            coord = eml.getGeospatialCoverages().get(index).getBoundingCoordinates().getMax().getLongitude();
                            if (coord == null) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.max.longitude", action.getText("validation.required", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.max.longitude") }));
                            } else if (Double.isNaN(coord)) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.max.longitude", action.getText("validation.invalid", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.max.longitude") }));
                            }
                            coord = eml.getGeospatialCoverages().get(index).getBoundingCoordinates().getMax().getLatitude();
                            if (coord == null) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.max.latitude", action.getText("validation.required", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.max.latitude") }));
                            } else if (Double.isNaN(coord)) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.max.latitude", action.getText("validation.invalid", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.max.latitude") }));
                            }
                            coord = eml.getGeospatialCoverages().get(index).getBoundingCoordinates().getMin().getLatitude();
                            if (coord == null) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.min.latitude", action.getText("validation.required", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.min.latitude") }));
                            } else if (Double.isNaN(coord)) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].boundingCoordinates.min.latitude", action.getText("validation.invalid", new String[] { action.getText("eml.geospatialCoverages.boundingCoordinates.min.latitude") }));
                            }
                            /* description - mandatory and greater than 2 chars */
                            if (StringUtils.isBlank(eml.getGeospatialCoverages().get(index).getDescription())) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].description", action.getText("validation.required", new String[] { action.getText("eml.geospatialCoverages.description") }));
                            } else if (!exists(eml.getGeospatialCoverages().get(index).getDescription(), 2)) {
                                action.addFieldError("eml.geospatialCoverages[" + index + "].description", action.getText("validation.short", new String[] { action.getText("eml.geospatialCoverages.description"), "2" }));
                            }
                        }
                    }
                } else {
                    // If all fields are empty, the <coverage> label in eml.xml will be removed.
                    eml.getGeospatialCoverages().clear();
                }
                break;
            case TAXANOMIC_COVERAGE_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isTaxonomicPageEmpty(eml)) {
                    // scientific name is required
                    int index = 0;
                    for (TaxonomicCoverage tc : eml.getTaxonomicCoverages()) {
                        int kw = 0;
                        if (tc != null) {
                            for (TaxonKeyword k : tc.getTaxonKeywords()) {
                                if (!exists(k.getScientificName())) {
                                    action.addFieldError("eml.taxonomicCoverages[" + index + "].taxonKeywords[" + kw + "].scientificName", action.getText("validation.required", new String[] { action.getText("eml.taxonomicCoverages.taxonKeyword.scientificName") }));
                                }
                                kw++;
                            }
                        }
                        index++;
                    }
                }
                break;
            case TEMPORAL_COVERAGE_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isTemporalPageEmpty(eml)) {
                    int index = 0;
                    for (TemporalCoverage tc : eml.getTemporalCoverages()) {
                        if (tc.getType() == TemporalCoverageType.SINGLE_DATE && !exists(tc.getStartDate())) {
                            action.addFieldError("eml.temporalCoverages[" + index + "].startDate", action.getText("validation.required", new String[] { action.getText("eml.temporalCoverages.startDate") }));
                        }
                        if (tc.getType() == TemporalCoverageType.DATE_RANGE) {
                            if (!exists(tc.getStartDate())) {
                                action.addFieldError("eml.temporalCoverages[" + index + "].startDate", action.getText("validation.required", new String[] { action.getText("eml.temporalCoverages.startDate") }));
                            }
                            if (!exists(tc.getEndDate())) {
                                action.addFieldError("eml.temporalCoverages[" + index + "].endDate", action.getText("validation.required", new String[] { action.getText("eml.temporalCoverages.endDate") }));
                            }
                        }
                        if (tc.getType() == TemporalCoverageType.FORMATION_PERIOD && !exists(tc.getFormationPeriod())) {
                            action.addFieldError("eml.temporalCoverages[" + index + "].formationPeriod", action.getText("validation.required", new String[] { action.getText("eml.temporalCoverages.formationPeriod") }));
                        }
                        if (tc.getType() == TemporalCoverageType.LIVING_TIME_PERIOD && !exists(tc.getLivingTimePeriod())) {
                            action.addFieldError("eml.temporalCoverages[" + index + "].livingTimePeriod", action.getText("validation.required", new String[] { action.getText("eml.temporalCoverages.livingTimePeriod") }));
                        }
                        index++;
                    }
                }
                break;
            case KEYWORDS_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isKeywordsPageEmpty(eml)) {
                    int index = 0;
                    for (KeywordSet ks : eml.getKeywords()) {
                        // TODO: remove check for "null" after fixing problem in gbif-metadata-profile
                        if (!exists(ks.getKeywordsString()) || ks.getKeywordsString().equalsIgnoreCase("null")) {
                            action.addFieldError("eml.keywords[" + index + "].keywordsString", action.getText("validation.required", new String[] { action.getText("eml.keywords.keywordsString") }));
                        }
                        if (!exists(ks.getKeywordThesaurus())) {
                            action.addFieldError("eml.keywords[" + index + "].keywordThesaurus", action.getText("validation.required", new String[] { action.getText("eml.keywords.keywordThesaurus") }));
                        }
                        index++;
                    }
                }
                break;
            case PARTIES_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isAgentsListEmpty(eml.getAssociatedParties())) {
                    for (int index = 0; index < eml.getAssociatedParties().size(); index++) {
                        Agent ap = eml.getAssociatedParties().get(index);
                        // firstName - optional. But if firstName exists, lastName have to exist
                        if (exists(ap.getFirstName()) && !exists(ap.getLastName())) {
                            action.addFieldError("eml.associatedParties[" + index + "].lastName", action.getText("validation.firstname.lastname"));
                        }
                        // directory and personnel id both required (if either is supplied)
                        if (!ap.getUserIds().isEmpty()) {
                            if (exists(ap.getUserIds().get(0).getDirectory()) && !exists(ap.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.associatedParties[" + index + "].userIds[0].identifier", action.getText("validation.personnel"));
                            } else if (!exists(ap.getUserIds().get(0).getDirectory()) && exists(ap.getUserIds().get(0).getIdentifier())) {
                                action.addFieldError("eml.associatedParties[" + index + "].userIds[0].directory", action.getText("validation.directory"));
                            }
                        }
                        // At least one of organisation, position, or a lastName have to exist
                        if (!exists(ap.getOrganisation()) && !exists(ap.getLastName()) && !exists(ap.getPosition())) {
                            action.addActionError(action.getText("validation.lastname.organisation.position"));
                            action.addFieldError("eml.associatedParties[" + index + "].organisation", action.getText("validation.required", new String[] { action.getText("eml.associatedParties.organisation") }));
                            action.addFieldError("eml.associatedParties[" + index + "].lastName", action.getText("validation.required", new String[] { action.getText("eml.associatedParties.lastName") }));
                            action.addFieldError("eml.associatedParties[" + index + "].position", action.getText("validation.required", new String[] { action.getText("eml.associatedParties.position") }));
                        }
                        /* email is optional. But if it exists, should be a valid email address */
                        if (exists(ap.getEmail()) && !isValidEmail(ap.getEmail())) {
                            action.addFieldError("eml.associatedParties[" + index + "].email", action.getText("validation.invalid", new String[] { action.getText("eml.associatedParties.email") }));
                        }
                        /* phone is optional. But if it exists, should match the pattern */
                        if (exists(ap.getPhone()) && !isValidPhoneNumber(ap.getPhone())) {
                            action.addFieldError("eml.associatedParties[" + index + "].phone", action.getText("validation.invalid", new String[] { action.getText("eml.associatedParties.phone") }));
                        }
                        /* Validate the homepage URL from each associated parties */
                        if (ap.getHomepage() != null) {
                            if (formatURL(ap.getHomepage()) == null) {
                                action.addFieldError("eml.associatedParties[" + index + "].homepage", action.getText("validation.invalid", new String[] { action.getText("eml.associatedParties.homepage") }));
                            } else {
                                ap.setHomepage(formatURL(ap.getHomepage()));
                            }
                        }
                    }
                }
                break;
            case PROJECT_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isProjectPageEmpty(eml)) {
                    // title is required
                    if (!exists(eml.getProject().getTitle()) || eml.getProject().getTitle().trim().length() == 0) {
                        action.addFieldError("eml.project.title", action.getText("validation.required", new String[] { action.getText("eml.project.title") }));
                    }
                    // Personnel list: at least one field has to have had data entered into it to qualify for validation
                    if (isAgentsListEmpty(eml.getProject().getPersonnel())) {
                        action.addActionError(action.getText("eml.project.personnel.required"));
                    } else {
                        for (int index = 0; index < eml.getProject().getPersonnel().size(); index++) {
                            Agent p = eml.getProject().getPersonnel().get(index);
                            // firstName - optional. But if firstName exists, lastName have to exist
                            if (exists(p.getFirstName()) && !exists(p.getLastName())) {
                                action.addFieldError("eml.project.personnel[" + index + "].lastName", action.getText("validation.firstname.lastname"));
                            } else // At least a lastName has to exist
                            if (!exists(p.getLastName())) {
                                action.addFieldError("eml.project.personnel[" + index + "].lastName", action.getText("validation.required", new String[] { action.getText("eml.project.personnel.lastName") }));
                            }
                            // directory and personnel id both required (if either is supplied)
                            if (!p.getUserIds().isEmpty()) {
                                if (exists(p.getUserIds().get(0).getDirectory()) && !exists(p.getUserIds().get(0).getIdentifier())) {
                                    action.addFieldError("eml.project.personnel[" + index + "].userIds[0].identifier", action.getText("validation.personnel"));
                                } else if (!exists(p.getUserIds().get(0).getDirectory()) && exists(p.getUserIds().get(0).getIdentifier())) {
                                    action.addFieldError("eml.project.personnel[" + index + "].userIds[0].directory", action.getText("validation.directory"));
                                }
                            }
                        }
                    }
                }
                break;
            case METHODS_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isMethodsPageEmpty(eml)) {
                    boolean emptyFields = false;
                    if (StringUtils.isBlank(eml.getSampleDescription()) && StringUtils.isBlank(eml.getStudyExtent()) && StringUtils.isBlank(eml.getQualityControl())) {
                        eml.setSampleDescription(null);
                        eml.setStudyExtent(null);
                        eml.setQualityControl(null);
                        emptyFields = true;
                    }
                    // method step required
                    int index = 0;
                    for (String method : eml.getMethodSteps()) {
                        if (method.trim().length() == 0) {
                            if (emptyFields && index == 0) {
                                eml.getMethodSteps().clear();
                                break;
                            } else {
                                action.addFieldError("eml.methodSteps[" + index + "]", action.getText("validation.required", new String[] { action.getText("validation.field.required") }));
                            }
                        }
                        index++;
                    }
                    // both study extent and sampling description required if either one is present
                    if (!emptyFields) {
                        if (StringUtils.isNotBlank(eml.getSampleDescription()) && StringUtils.isBlank(eml.getStudyExtent())) {
                            action.addFieldError("eml.studyExtent", action.getText("validation.required", new String[] { action.getText("eml.studyExtent") }));
                        }
                        if (StringUtils.isNotBlank(eml.getStudyExtent()) && StringUtils.isBlank(eml.getSampleDescription())) {
                            action.addFieldError("eml.sampleDescription", action.getText("validation.required", new String[] { action.getText("eml.sampleDescription") }));
                        }
                    }
                }
                break;
            case CITATIONS_SECTION:
                // of citation is turned on
                if (!isCitationsPageEmpty(eml) || resource.isCitationAutoGenerated()) {
                    // recreate the auto-generated citation if auto-generation is turned on
                    if (resource.isCitationAutoGenerated()) {
                        // resource homepage is potential citation identifier
                        URI homepage = cfg.getResourceVersionUri(resource.getShortname(), resource.getNextVersion());
                        String citation = resource.generateResourceCitation(resource.getNextVersion(), homepage);
                        eml.getCitation().setCitation(citation);
                    }
                    // evaluate Citation
                    if (eml.getCitation() != null) {
                        // citation identifier must be between 2 and 200 characters long
                        if (StringUtils.isNotBlank(eml.getCitation().getIdentifier()) && !existsInRange(eml.getCitation().getIdentifier(), 2, 200)) {
                            action.addFieldError("eml.citation.identifier", action.getText("validation.field.invalidSize", new String[] { action.getText("eml.citation.identifier"), "2", "200" }));
                        }
                        // citation text is required, while identifier attribute is optional
                        if (exists(eml.getCitation().getIdentifier()) && !exists(eml.getCitation().getCitation())) {
                            action.addFieldError("eml.citation.citation", action.getText("validation.required", new String[] { action.getText("eml.citation.citation") }));
                        }
                    }
                    int index = 0;
                    for (Citation citation : eml.getBibliographicCitations()) {
                        if (StringUtils.isNotBlank(citation.getIdentifier()) && !exists(citation.getIdentifier())) {
                            action.addFieldError("eml.bibliographicCitationSet.bibliographicCitations[" + index + "].identifier", action.getText("validation.field.blank", new String[] { action.getText("eml.bibliographicCitationSet.bibliographicCitations.identifier") }));
                        }
                        if (!exists(citation.getCitation())) {
                            action.addFieldError("eml.bibliographicCitationSet.bibliographicCitations[" + index + "].citation", action.getText("validation.required", new String[] { action.getText("validation.field.required") }));
                        }
                        index++;
                    }
                }
                break;
            case COLLECTIONS_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isCollectionsPageEmpty(eml)) {
                    // at least one collection with name filled in is required
                    if (eml.getCollections().isEmpty()) {
                        action.addActionError(action.getText("eml.collection.required"));
                    }
                    for (int index = 0; index < eml.getCollections().size(); index++) {
                        Collection c = eml.getCollections().get(index);
                        // collection name is required, collection id and parent collection id are NOT required
                        if (!exists(c.getCollectionName())) {
                            action.addFieldError("eml.collections[" + index + "].collectionName", action.getText("validation.required", new String[] { action.getText("eml.collectionName") }));
                        }
                    }
                    // TODO ensure this validation works with drop down, and bypasses default
                    for (int index = 0; index < eml.getSpecimenPreservationMethods().size(); index++) {
                        String preservationMethod = eml.getSpecimenPreservationMethods().get(index);
                        // collection name is required, collection id and parent collection id are NOT required
                        if (StringUtils.isBlank(preservationMethod)) {
                            action.addFieldError("eml.specimenPreservationMethods[" + index + "]", action.getText("validation.required", new String[] { action.getText("eml.specimenPreservationMethod") }));
                        }
                    }
                    int index = 0;
                    for (JGTICuratorialUnit jcu : eml.getJgtiCuratorialUnits()) {
                        if (jcu.getType() == JGTICuratorialUnitType.COUNT_RANGE) {
                            if (!exists(jcu.getRangeStart())) {
                                action.addFieldError("eml.jgtiCuratorialUnits[" + index + "].rangeStart", action.getText("validation.required", new String[] { action.getText("validation.field.required") }));
                            }
                            if (!exists(jcu.getRangeEnd())) {
                                action.addFieldError("eml.jgtiCuratorialUnits[" + index + "].rangeEnd", action.getText("validation.required", new String[] { action.getText("validation.field.required") }));
                            }
                        }
                        if (jcu.getType() == JGTICuratorialUnitType.COUNT_WITH_UNCERTAINTY) {
                            if (!exists(jcu.getRangeMean())) {
                                action.addFieldError("eml.jgtiCuratorialUnits[" + index + "].rangeMean", action.getText("validation.required", new String[] { action.getText("validation.field.required") }));
                            }
                            if (!exists(jcu.getUncertaintyMeasure())) {
                                action.addFieldError("eml.jgtiCuratorialUnits[" + index + "].uncertaintyMeasure", action.getText("validation.required", new String[] { action.getText("validation.field.required") }));
                            }
                        }
                        if (!exists(jcu.getUnitType())) {
                            action.addFieldError("eml.jgtiCuratorialUnits[" + index + "].unitType", action.getText("validation.required", new String[] { action.getText("eml.jgtiCuratorialUnits.unitType") }));
                        }
                        index++;
                    }
                }
                break;
            case PHYSICAL_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isPhysicalPageEmpty(eml)) {
                    // null or empty URLs bypass validation
                    if (StringUtils.isNotBlank(eml.getDistributionUrl())) {
                        // retrieve a formatted homepage URL including scheme component
                        String formattedUrl = formatURL(eml.getDistributionUrl());
                        if (formattedUrl == null || !isWellFormedURI(formattedUrl)) {
                            action.addFieldError("eml.distributionUrl", action.getText("validation.invalid", new String[] { action.getText("eml.distributionUrl") }));
                        } else {
                            eml.setDistributionUrl(formattedUrl);
                        }
                    }
                    // character set, download URL, and data format are required
                    int index = 0;
                    for (PhysicalData pd : eml.getPhysicalData()) {
                        // name required
                        if (!exists(pd.getName())) {
                            action.addFieldError("eml.physicalData[" + index + "].name", action.getText("validation.required", new String[] { action.getText("eml.physicalData.name") }));
                        }
                        // character set required
                        if (!exists(pd.getCharset())) {
                            action.addFieldError("eml.physicalData[" + index + "].charset", action.getText("validation.required", new String[] { action.getText("eml.physicalData.charset") }));
                        }
                        // download URL required
                        if (!exists(pd.getDistributionUrl())) {
                            action.addFieldError("eml.physicalData[" + index + "].distributionUrl", action.getText("validation.required", new String[] { action.getText("eml.physicalData.distributionUrl") }));
                        }
                        // data format required
                        if (!exists(pd.getFormat())) {
                            action.addFieldError("eml.physicalData[" + index + "].format", action.getText("validation.required", new String[] { action.getText("eml.physicalData.format") }));
                        }
                        // data format version is optional - so skip
                        /* Validate distribution URL form each Physical data */
                        String formattedDistributionUrl = formatURL(pd.getDistributionUrl());
                        if (formattedDistributionUrl == null || !isWellFormedURI(formattedDistributionUrl)) {
                            action.addFieldError("eml.physicalData[" + index + "].distributionUrl", action.getText("validation.invalid", new String[] { action.getText("eml.physicalData.distributionUrl") }));
                        } else {
                            pd.setDistributionUrl(formattedDistributionUrl);
                        }
                        index++;
                    }
                }
                break;
            case ADDITIONAL_SECTION:
                // at least one field has to have had data entered into it to qualify for validation
                if (!isAdditionalPageEmpty(eml)) {
                    // ensure each alternative id is longer than min length
                    int index = 0;
                    for (String ai : eml.getAlternateIdentifiers()) {
                        if (!exists(ai)) {
                            action.addFieldError("eml.alternateIdentifiers[" + index + "]", action.getText("validation.required", new String[] { action.getText("eml.alternateIdentifier") }));
                        }
                        index++;
                    }
                }
                break;
            default:
                break;
        }
    }
}
Also used : Agent(org.gbif.metadata.eml.Agent) Eml(org.gbif.metadata.eml.Eml) TaxonKeyword(org.gbif.metadata.eml.TaxonKeyword) TemporalCoverage(org.gbif.metadata.eml.TemporalCoverage) URI(java.net.URI) Point(org.gbif.metadata.eml.Point) KeywordSet(org.gbif.metadata.eml.KeywordSet) TaxonomicCoverage(org.gbif.metadata.eml.TaxonomicCoverage) Collection(org.gbif.metadata.eml.Collection) Citation(org.gbif.metadata.eml.Citation) JGTICuratorialUnit(org.gbif.metadata.eml.JGTICuratorialUnit) PhysicalData(org.gbif.metadata.eml.PhysicalData)

Aggregations

TaxonomicCoverage (org.gbif.metadata.eml.TaxonomicCoverage)4 TaxonKeyword (org.gbif.metadata.eml.TaxonKeyword)3 ArrayList (java.util.ArrayList)2 Paragraph (com.lowagie.text.Paragraph)1 Phrase (com.lowagie.text.Phrase)1 DefaultLocaleProviderFactory (com.opensymphony.xwork2.DefaultLocaleProviderFactory)1 LocaleProviderFactory (com.opensymphony.xwork2.LocaleProviderFactory)1 Container (com.opensymphony.xwork2.inject.Container)1 File (java.io.File)1 BigDecimal (java.math.BigDecimal)1 URI (java.net.URI)1 Date (java.util.Date)1 LinkedHashMap (java.util.LinkedHashMap)1 AppConfig (org.gbif.ipt.config.AppConfig)1 DataDir (org.gbif.ipt.config.DataDir)1 Resource (org.gbif.ipt.model.Resource)1 User (org.gbif.ipt.model.User)1 VersionHistory (org.gbif.ipt.model.VersionHistory)1 RegistrationManager (org.gbif.ipt.service.admin.RegistrationManager)1 VocabulariesManager (org.gbif.ipt.service.admin.VocabulariesManager)1