Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CSW / Configuration of the capabilities is now done using a service metadata record #4390

Merged
Merged
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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;
}
}
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading