Skip to content

Commit

Permalink
CSW / Configuration of the capabilities is now done using a service m…
Browse files Browse the repository at this point in the history
…etadata record (#4390)

* CSW / Configuration of the capabilities is now done using a service metadata record.

* CSW / Configuration of the capabilities is now done using a service metadata record.

* CSW / Configuration of the capabilities is now done using a service metadata record / Add warning in case of error. Language config is made in the record, not from the db.

* CSW / Configuration of the capabilities is now done using a service metadata record / Add warning in case of error. Multilingual support.

* CSW / Configuration of the capabilities is now done using a service metadata record / Add warning in case of error. ISO19139 support and language.

* CSW / Configuration of the capabilities is now done using a service metadata record / Add warning in case of error. Displaye service title.

* Cleaning.

* CSW / Configuration of the capabilities is now done using a service metadata record / Add warning in case of error. Portal CSW.

* Replace id by uuid.
  • Loading branch information
fxprunayre committed Jan 28, 2020
1 parent 293acb0 commit 62590c3
Show file tree
Hide file tree
Showing 20 changed files with 994 additions and 764 deletions.
Expand Up @@ -82,7 +82,7 @@ public class Settings {
public static final String SYSTEM_SELECTIONMANAGER_MAXRECORDS = "system/selectionmanager/maxrecords";
public static final String SYSTEM_CSW_ENABLE = "system/csw/enable";
public static final String SYSTEM_CSW_ENABLEWHENINDEXING = "system/csw/enabledWhenIndexing";
public static final String SYSTEM_CSW_CONTACT_ID = "system/csw/contactId";
public static final String SYSTEM_CSW_CAPABILITY_RECORD_UUID = "system/csw/capabilityRecordUuid";
public static final String SYSTEM_CSW_METADATA_PUBLIC = "system/csw/metadataPublic";
public static final String SYSTEM_USERSELFREGISTRATION_ENABLE = "system/userSelfRegistration/enable";
public static final String SYSTEM_USERSELFREGISTRATION_RECAPTCHA_ENABLE = "system/userSelfRegistration/recaptcha/enable";
Expand Down
Expand Up @@ -23,9 +23,7 @@

package org.fao.geonet.component.csw;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

import jeeves.server.context.ServiceContext;
import org.apache.commons.lang.StringUtils;
import org.fao.geonet.GeonetContext;
import org.fao.geonet.NodeInfo;
Expand All @@ -35,32 +33,31 @@
import org.fao.geonet.csw.common.exceptions.CatalogException;
import org.fao.geonet.csw.common.exceptions.NoApplicableCodeEx;
import org.fao.geonet.csw.common.exceptions.VersionNegotiationFailedEx;
import org.fao.geonet.domain.Address;
import org.fao.geonet.domain.Language;
import org.fao.geonet.domain.Metadata;
import org.fao.geonet.domain.Source;
import org.fao.geonet.domain.User;
import org.fao.geonet.kernel.AccessManager;
import org.fao.geonet.kernel.SchemaManager;
import org.fao.geonet.kernel.csw.CatalogConfiguration;
import org.fao.geonet.kernel.csw.CatalogService;
import org.fao.geonet.kernel.csw.services.AbstractOperation;
import org.fao.geonet.kernel.csw.services.getrecords.FieldMapper;
import org.fao.geonet.kernel.datamanager.IMetadataUtils;
import org.fao.geonet.kernel.search.LuceneConfig;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.kernel.setting.Settings;
import org.fao.geonet.lib.Lib;
import org.fao.geonet.repository.CswCapabilitiesInfo;
import org.fao.geonet.repository.CswCapabilitiesInfoFieldRepository;
import org.fao.geonet.repository.LanguageRepository;
import org.fao.geonet.repository.MetadataRepository;
import org.fao.geonet.repository.SourceRepository;
import org.fao.geonet.repository.UserRepository;
import org.fao.geonet.utils.Log;
import org.fao.geonet.utils.Xml;
import org.jdom.Comment;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.stereotype.Component;

import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -69,13 +66,6 @@
import java.util.Map;
import java.util.Set;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.ServletContext;

import jeeves.server.context.ServiceContext;
import jeeves.server.overrides.ConfigurationOverrides;

import static org.fao.geonet.kernel.setting.SettingManager.isPortRequired;

/**
Expand All @@ -96,6 +86,13 @@ public class GetCapabilities extends AbstractOperation implements CatalogService
private NodeInfo nodeinfo;
@Autowired
private SourceRepository sourceRepository;
@Autowired
private MetadataRepository metadataRepository;
@Autowired
private IMetadataUtils metadataUtils;
@Autowired
private AccessManager accessManager;


public String getName() {
return NAME;
Expand All @@ -107,87 +104,82 @@ public Element execute(Element request, ServiceContext context) throws CatalogEx
checkAcceptVersions(request);

GeonetContext gc = (GeonetContext) context.getHandlerContext(Geonet.CONTEXT_NAME);
boolean inspireEnabled = gc.getBean(SettingManager.class).getValueAsBool(Settings.SYSTEM_INSPIRE_ENABLE, false);


//--- return capabilities

Path file;

if (inspireEnabled) {
file = context.getAppPath().resolve("xml").resolve("csw").resolve("capabilities_inspire.xml");
} else {
file = context.getAppPath().resolve("xml").resolve("csw").resolve("capabilities.xml");
}
boolean isFromRecord = false;

try {
Element capabilities = Xml.loadFile(file);
ServletContext servletContext = null;
if (context.getServlet() != null) {
servletContext = context.getServlet().getServletContext();
String recordUuidToUseForCapability = gc.getBean(SettingManager.class).getValue(Settings.SYSTEM_CSW_CAPABILITY_RECORD_UUID);
if (!NodeInfo.DEFAULT_NODE.equals(context.getNodeId())) {
final Source source = sourceRepository.findOne(nodeinfo.getId());
if(source.getServiceRecord() != null) {
recordUuidToUseForCapability = source.getServiceRecord().toString();
}
ConfigurationOverrides.DEFAULT.updateWithOverrides(file.toString(), servletContext, context.getAppPath(), capabilities);

String cswServiceSpecificContraint = request.getChildText(Geonet.Elem.FILTER);
setKeywords(capabilities, context, cswServiceSpecificContraint);
setOperationsParameters(capabilities);

String currentLanguage = "";

// INSPIRE: Use language parameter if available, otherwise use default (using context.getLanguage())
if (inspireEnabled) {
String isoLangParamValue = request.getAttributeValue("language");


final LanguageRepository languageRepository = context.getBean(LanguageRepository.class);
List<Language> languageList = languageRepository.findAllByInspireFlag(true);
}

List<String> langCodes = Lists.transform(languageList, new Function<Language, String>() {
@Nullable
@Override
public String apply(@Nonnull Language input) {
return input.getId();
Element capabilities = null;
String message = null;
if (StringUtils.isNotEmpty(recordUuidToUseForCapability) && !"-1".equals(recordUuidToUseForCapability)) {
Metadata record = metadataRepository.findOneByUuid(recordUuidToUseForCapability);
if (record != null) {
try {
if (accessManager.isVisibleToAll(String.valueOf(record.getId()))) {
String conversionFilename = "record-to-csw-capabilities.xsl";
String requestLanguage = request.getAttributeValue("language");
Map<String, Object> parameters = new HashMap<>();
parameters.put("outputLanguage", requestLanguage == null ? "" : requestLanguage);
Path conversion = context.getAppPath().resolve(Geonet.Path.CSW).resolve(conversionFilename);
capabilities = Xml.transform(record.getXmlData(false), conversion, parameters);
isFromRecord = true;
} else {
message = String.format(
"Record with UUID %s is not public and can't be used to build CSW GetCapabilities document. " +
"Choose another record or publish this one.", record.getUuid());
Log.warning(Geonet.CSW, message);
}
});
} catch (Exception e) {
message = String.format(
"Error during retrieval of record with UUID %s. Error is: %s.", record.getUuid(), e.getMessage());
Log.warning(Geonet.CSW, message);
}
} else {
// TODO: Add the message to the GetCapabilities doc ?
message = String.format(
"Record with id %s is not available in the catalogue. Check the CSW configuration and choose an existing record.",
recordUuidToUseForCapability);
Log.warning(Geonet.CSW, message);
}
}

if (isoLangParamValue != null) {
// Retrieve GN language id from Iso language id
if (langCodes.contains(isoLangParamValue)) {
currentLanguage = isoLangParamValue;
}
if (capabilities == null) {
Path file = context.getAppPath().resolve("xml").resolve("csw").resolve("capabilities.xml");
try {
capabilities = Xml.loadFile(file);
if (StringUtils.isNotEmpty(message)) {
capabilities.addContent(new Comment("WARNING: " + message));
}
} catch (JDOMException e) {
Log.warning(Geonet.CSW, String.format("XML encoding error in file /xml/csw/capabilities.xml. Error is %s.", e.getMessage()));
} catch (NoSuchFileException e) {
Log.warning(Geonet.CSW, "File /xml/csw/capabilities.xml not found. Check catalogue config file.");
}
}

String defaultLanguageId = context.getLanguage();
try {
Language defaultLanguage = languageRepository.findOneByDefaultLanguage();
if (capabilities == null) {
throw new NoApplicableCodeEx("Failed to load capabilities from configuration files or from record. Check the CSW configuration.");
}

if (StringUtils.isEmpty(currentLanguage)) {
currentLanguage = defaultLanguage.getId();
defaultLanguageId = defaultLanguage.getId();
}
} catch (EmptyResultDataAccessException e) {
Log.error(Geonet.CSW, "No default language set in database languages table. " +
"You MUST set one default language (using isDefault column). " +
"Using session language as default. Error is: " + e.getMessage());
currentLanguage = context.getLanguage();
}
try {
String cswServiceSpecificContraint = request.getChildText(Geonet.Elem.FILTER);

setInspireLanguages(capabilities, langCodes, currentLanguage, defaultLanguageId);
} else {
currentLanguage = context.getLanguage();
if (!isFromRecord) {
setKeywords(capabilities, context, cswServiceSpecificContraint);
}
setOperationsParameters(capabilities);

final CswCapabilitiesInfoFieldRepository infoRepository = context.getBean(CswCapabilitiesInfoFieldRepository.class);
CswCapabilitiesInfo cswCapabilitiesInfo = infoRepository.findCswCapabilitiesInfo(currentLanguage);

// Retrieve contact data from users table
String contactId = gc.getBean(SettingManager.class).getValue(Settings.SYSTEM_CSW_CONTACT_ID);
if ((contactId == null) || (contactId.equals(""))) {
contactId = "-1";
String currentLanguage = request.getAttributeValue("language");
if (currentLanguage == null) {
currentLanguage = context.getLanguage();
}
User user = context.getBean(UserRepository.class).findOne(contactId);

substitute(context, capabilities, cswCapabilitiesInfo, user, currentLanguage);
substitute(context, capabilities, currentLanguage);

handleSections(request, capabilities);

Expand Down Expand Up @@ -331,7 +323,7 @@ private void handleSections(Element request, Element capabilities) {

}

private void substitute(ServiceContext context, Element capab, CswCapabilitiesInfo cswCapabilitiesInfo, User contact, String langId) throws Exception {
private void substitute(ServiceContext context, Element capab, String langId) throws Exception {
GeonetContext gc = (GeonetContext) context.getHandlerContext(Geonet.CONTEXT_NAME);
SettingManager sm = gc.getBean(SettingManager.class);

Expand All @@ -354,52 +346,15 @@ private void substitute(ServiceContext context, Element capab, CswCapabilitiesIn

vars.put("$SERVLET", context.getBaseUrl());

// Set CSW contact information
if (contact != null) {
vars.put("$IND_NAME", contact.getName() + " " + contact.getSurname());
vars.put("$ORG_NAME", contact.getOrganisation());
vars.put("$POS_NAME", contact.getProfile().name());
vars.put("$VOICE", "");
vars.put("$FACSCIMILE", "");
final Address address = contact.getPrimaryAddress();
vars.put("$DEL_POINT", address.getAddress());
vars.put("$CITY", address.getCity());
vars.put("$ADMIN_AREA", address.getState());
vars.put("$POSTAL_CODE", address.getZip());
vars.put("$COUNTRY", address.getCountry());
vars.put("$EMAIL", contact.getEmail());
vars.put("$HOUROFSERVICE", "");
vars.put("$CONTACT_INSTRUCTION", "");
} else {
vars.put("$IND_NAME", "");
vars.put("$ORG_NAME", "");
vars.put("$POS_NAME", "");
vars.put("$VOICE", "");
vars.put("$FACSCIMILE", "");
vars.put("$DEL_POINT", "");
vars.put("$CITY", "");
vars.put("$ADMIN_AREA", "");
vars.put("$POSTAL_CODE", "");
vars.put("$COUNTRY", "");
vars.put("$EMAIL", "");
vars.put("$HOUROFSERVICE", "");
vars.put("$CONTACT_INSTRUCTION", "");
}
boolean isTitleDefined = false;
if (!NodeInfo.DEFAULT_NODE.equals(nodeinfo.getId())) {
final Source source = sourceRepository.findOne(nodeinfo.getId());
if (source != null) {
vars.put("$TITLE", source.getLabelTranslations().get(langId));
isTitleDefined = true;
}
}
if (!isTitleDefined) {
vars.put("$TITLE", cswCapabilitiesInfo.getTitle());
String sourceUuid = NodeInfo.DEFAULT_NODE.equals(nodeinfo.getId()) ? sm.getSiteId() : nodeinfo.getId();
final Source source = sourceRepository.findOne(sourceUuid);
if (source != null) {
vars.put("$TITLE", source.getLabelTranslations().get(langId));
isTitleDefined = true;
} else {
vars.put("$TITLE", sm.getSiteName());
}
vars.put("$ABSTRACT", cswCapabilitiesInfo.getAbstract());
vars.put("$FEES", cswCapabilitiesInfo.getFees());
vars.put("$ACCESS_CONSTRAINTS", cswCapabilitiesInfo.getAccessConstraints());

vars.put("$LOCALE", langId);

Lib.element.substitute(capab, vars);
Expand Down
10 changes: 10 additions & 0 deletions domain/src/main/java/org/fao/geonet/domain/Source.java
Expand Up @@ -67,6 +67,7 @@ public class Source extends Localized {
private String logo;
private String filter;
private String uiConfig;
private String serviceRecord;
private ISODate creationDate = new ISODate();
private Integer groupOwner;

Expand Down Expand Up @@ -269,4 +270,13 @@ public Source setGroupOwner(Integer groupOwner) {
this.groupOwner = groupOwner;
return this;
}

@Column(name = "serviceRecord")
public String getServiceRecord() {
return serviceRecord;
}

public void setServiceRecord(String serviceRecord) {
this.serviceRecord = serviceRecord;
}
}
Expand Up @@ -41,7 +41,7 @@ public class CswConfigurationResponse implements Serializable {
private static final long serialVersionUID = -4426385060234828544L;
private boolean cswEnabled;
private boolean cswMetadataPublic;
private int cswContactId;
private int capabilityRecordUuid;
@XmlElement(name = "record")
private List<CswCapabilitiesInfoField> capabilitiesInfoFields;

Expand All @@ -61,12 +61,12 @@ public void setCswMetadataPublic(boolean cswMetadataPublic) {
this.cswMetadataPublic = cswMetadataPublic;
}

public int getCswContactId() {
return cswContactId;
public int getCapabilityRecordUuid() {
return capabilityRecordUuid;
}

public void setCswContactId(int cswContactId) {
this.cswContactId = cswContactId;
public void setCapabilityRecordUuid(int capabilityRecordUuid) {
this.capabilityRecordUuid = capabilityRecordUuid;
}

public List<CswCapabilitiesInfoField> getCapabilitiesInfoFields() {
Expand Down
Expand Up @@ -304,6 +304,7 @@ private void updateSource(String sourceIdentifier,
entity.setType(source.getType());
entity.setFilter(source.getFilter());
entity.setGroupOwner(source.getGroupOwner());
entity.setServiceRecord(source.getServiceRecord());
entity.setUiConfig(source.getUiConfig());
entity.setLogo(source.getLogo());
Map<String, String> labelTranslations = source.getLabelTranslations();
Expand Down
14 changes: 4 additions & 10 deletions services/src/main/java/org/fao/geonet/guiservices/csw/Get.java
Expand Up @@ -23,11 +23,9 @@
package org.fao.geonet.guiservices.csw;

import org.fao.geonet.ApplicationContextHolder;
import org.fao.geonet.domain.CswCapabilitiesInfoField;
import org.fao.geonet.domain.responses.CswConfigurationResponse;
import org.fao.geonet.kernel.setting.SettingManager;
import org.fao.geonet.kernel.setting.Settings;
import org.fao.geonet.repository.CswCapabilitiesInfoFieldRepository;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
Expand All @@ -47,18 +45,14 @@ CswConfigurationResponse exec() throws Exception {

CswConfigurationResponse response = new CswConfigurationResponse();

String cswContactIdValue = sm.getValue(Settings.SYSTEM_CSW_CONTACT_ID);
if (cswContactIdValue == null) {
cswContactIdValue = "-1";
String capabilityRecordUuid = sm.getValue(Settings.SYSTEM_CSW_CAPABILITY_RECORD_UUID);
if (capabilityRecordUuid == null) {
capabilityRecordUuid = "-1";
}

final CswCapabilitiesInfoFieldRepository infoFieldRepository = applicationContext.getBean(CswCapabilitiesInfoFieldRepository.class);
java.util.List<CswCapabilitiesInfoField> capabilitiesInfoFields = infoFieldRepository.findAll(); //AsXml();

response.setCswEnabled(sm.getValueAsBool(Settings.SYSTEM_CSW_ENABLE));
response.setCswMetadataPublic(sm.getValueAsBool(Settings.SYSTEM_CSW_METADATA_PUBLIC));
response.setCswContactId(Integer.parseInt(cswContactIdValue));
response.setCapabilitiesInfoFields(capabilitiesInfoFields);
response.setCapabilityRecordUuid(Integer.parseInt(capabilityRecordUuid));

return response;
}
Expand Down

0 comments on commit 62590c3

Please sign in to comment.