108 lines
3.8 KiB
Java
108 lines
3.8 KiB
Java
package eu.dnetlib.is.util;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.StringReader;
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
import javax.xml.XMLConstants;
|
|
import javax.xml.transform.stream.StreamSource;
|
|
import javax.xml.validation.Schema;
|
|
import javax.xml.validation.SchemaFactory;
|
|
import javax.xml.validation.Validator;
|
|
|
|
import org.apache.commons.io.IOUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.logging.Log;
|
|
import org.apache.commons.logging.LogFactory;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.config.BeanDefinition;
|
|
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
|
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
|
import org.springframework.http.MediaType;
|
|
import org.springframework.stereotype.Component;
|
|
import org.xml.sax.SAXException;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
import eu.dnetlib.is.resource.model.ResourceType;
|
|
import eu.dnetlib.is.resource.repository.ResourceTypeRepository;
|
|
|
|
@Component
|
|
public class ResourceValidator {
|
|
|
|
private final Log log = LogFactory.getLog(ResourceValidator.class);
|
|
|
|
@Autowired
|
|
private ResourceTypeRepository resourceTypeRepository;
|
|
|
|
public void validate(final String type, final String content) throws InformationServiceException {
|
|
|
|
final ResourceType rtype = resourceTypeRepository.findById(type).orElseThrow(() -> new InformationServiceException("Invalid type"));
|
|
|
|
if (rtype.getContentType().equals(MediaType.APPLICATION_XML_VALUE)) {
|
|
validateXml(type, content);
|
|
} else if (rtype.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
|
|
validateJSON(type, content);
|
|
}
|
|
}
|
|
|
|
private void validateXml(final String type, final String content) throws InformationServiceException {
|
|
final Schema schema = getXmlSchema(type);
|
|
if (schema == null) {
|
|
log.warn("no registered schema for " + type);
|
|
return;
|
|
}
|
|
final Validator validator = schema.newValidator();
|
|
|
|
try {
|
|
validator.validate(new StreamSource(new StringReader(content)));
|
|
} catch (final Exception e) {
|
|
throw new InformationServiceException("invalid resource", e);
|
|
}
|
|
}
|
|
|
|
private Schema getXmlSchema(final String type) {
|
|
try {
|
|
final InputStream is = getClass().getResourceAsStream("/schemas/" + type + ".xsd");
|
|
if (is == null) { return null; }
|
|
final String schemaSource = IOUtils.toString(is, StandardCharsets.UTF_8.name());
|
|
if (StringUtils.isBlank(schemaSource)) { return null; }
|
|
return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(new StreamSource(new StringReader(schemaSource)));
|
|
} catch (final SAXException | IOException e) {
|
|
log.fatal("cannot parse resource type schema", e);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void validateJSON(final String type, final String content) throws InformationServiceException {
|
|
final Class<?> clazz = getJsonClass(type);
|
|
if (clazz == null) {
|
|
log.warn("no registered Class for " + type);
|
|
}
|
|
final ObjectMapper mapper = new ObjectMapper();
|
|
|
|
try {
|
|
mapper.readValue(content, clazz);
|
|
} catch (final Exception e) {
|
|
throw new InformationServiceException("invalid resource", e);
|
|
}
|
|
}
|
|
|
|
private Class<?> getJsonClass(final String type) {
|
|
final ClassLoader classLoader = ResourceValidator.class.getClassLoader();
|
|
|
|
final ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(true);
|
|
|
|
provider.addIncludeFilter(new AnnotationTypeFilter(JsonResource.class));
|
|
provider.setResourceLoader(new PathMatchingResourcePatternResolver(classLoader));
|
|
|
|
for (final BeanDefinition bd : provider.findCandidateComponents("eu.dnetlib")) {
|
|
if (bd.getClass().getAnnotation(JsonResource.class).value().equals(type)) { return bd.getClass(); }
|
|
}
|
|
return null;
|
|
}
|
|
|
|
}
|