diff --git a/exist-core/src/main/java/org/exist/util/Configuration.java b/exist-core/src/main/java/org/exist/util/Configuration.java index bb7c85e2236..e8d53d1e556 100644 --- a/exist-core/src/main/java/org/exist/util/Configuration.java +++ b/exist-core/src/main/java/org/exist/util/Configuration.java @@ -1196,22 +1196,64 @@ private void configureValidation(final Optional dbHome, final Element vali // Determine validation mode configureProperty(validation, XMLReaderObjectFactory.VALIDATION_MODE_ATTRIBUTE, PROPERTY_VALIDATION_MODE); - // cache - setProperty(XMLReaderObjectFactory.GRAMMAR_POOL, new GrammarPool()); - // Configure the Entity Resolver - final NodeList entityResolver = validation.getElementsByTagName(XMLReaderObjectFactory.CONFIGURATION_ENTITY_RESOLVER_ELEMENT_NAME); - if (entityResolver.getLength() == 0) { - return; + final NodeList entityResolverElements = validation.getElementsByTagName(XMLReaderObjectFactory.CONFIGURATION_ENTITY_RESOLVER_ELEMENT_NAME); + if (entityResolverElements.getLength() != 0) { + final Element elemEntityResolver = (Element) entityResolverElements.item(0); + configureEntityResolver(dbHome, elemEntityResolver); } + + // Configure the grammar pool + final NodeList grammarPoolElements = validation.getElementsByTagName(GrammarPool.GRAMMAR_POOL_ELEMENT); + configureGrammarCache(grammarPoolElements); + + } + + private void configureGrammarCache(final NodeList grammarCacheElements) { + if (grammarCacheElements.getLength() == 0) { + setProperty(GrammarPool.GRAMMAR_POOL_ELEMENT, new GrammarPool()); + + } else { + final Element grammarPoolElem = (Element) grammarCacheElements.item(0); + configureProperty(grammarPoolElem, GrammarPool.ATTRIBUTE_MAXIMUM_SIZE, + GrammarPool.PROPERTY_MAXIMUM_SIZE, Configuration::asInteger, null); + configureProperty(grammarPoolElem, GrammarPool.ATTRIBUTE_EXPIRE_AFTER_ACCESS, + GrammarPool.PROPERTY_EXPIRE_AFTER_ACCESS, Configuration::asInteger, null); + setProperty(GrammarPool.GRAMMAR_POOL_ELEMENT, + new GrammarPool(getInteger(GrammarPool.PROPERTY_MAXIMUM_SIZE), getInteger(GrammarPool.PROPERTY_EXPIRE_AFTER_ACCESS))); + } + } + + private void configureEntityResolver(final Optional dbHome, final Element entityResolverElement) { LOG.info("Creating xmlresolver.org OASIS Catalog resolver"); - final Element elemEntityResolver = (Element) entityResolver.item(0); - final NodeList nlCatalogs = elemEntityResolver.getElementsByTagName(XMLReaderObjectFactory.CONFIGURATION_CATALOG_ELEMENT_NAME); + final NodeList catalogElements = entityResolverElement + .getElementsByTagName(XMLReaderObjectFactory.CONFIGURATION_CATALOG_ELEMENT_NAME); + final Path webappHome = getWebappHome(dbHome, catalogElements); + + // Store all configured URIs + final List catalogUris = getCatalogUris(dbHome, catalogElements, webappHome); + setProperty(XMLReaderObjectFactory.CATALOG_URIS, catalogUris); + + // Create and Store the resolver + try { + final List>> catalogs = catalogUris.stream() + .map(catalogUri -> Tuple(catalogUri, Optional.empty())) + .toList(); + final Resolver resolver = ResolverFactory.newResolver(catalogs); + setProperty(XMLReaderObjectFactory.CATALOG_RESOLVER, resolver); + } catch (final URISyntaxException e) { + LOG.error("Unable to parse catalog uri: {}", e.getMessage(), e); + } + } + + /* + Determine webapps directory. SingleInstanceConfiguration cannot + be used at this phase. Trick is to check whether dbHOME is + pointing to a WEB-INF directory, meaning inside the war file. + */ + private static Path getWebappHome(final Optional dbHome, final NodeList catalogElements) { - // Determine webapps directory. SingleInstanceConfiguration cannot - // be used at this phase. Trick is to check whether dbHOME is - // pointing to a WEB-INF directory, meaning inside the war file. final Path webappHome = dbHome.map(h -> { if (FileUtils.fileName(h).endsWith("WEB-INF")) { return h.getParent().toAbsolutePath(); @@ -1220,15 +1262,18 @@ private void configureValidation(final Optional dbHome, final Element vali }).orElse(Paths.get("webapp").toAbsolutePath()); if (LOG.isDebugEnabled()) { - LOG.debug("Found {} catalog uri entries.", nlCatalogs.getLength()); + LOG.debug("Found {} catalog uri entries.", catalogElements.getLength()); LOG.debug("Using dbHome={}", dbHome); LOG.debug("using webappHome={}", webappHome); } + return webappHome; + } + private static List getCatalogUris(final Optional dbHome, final NodeList catalogElements, final Path webappHome) { // Get the Catalog URIs final List catalogUris = new ArrayList<>(); - for (int i = 0; i < nlCatalogs.getLength(); i++) { - final String uriAttributeValue = ((Element) nlCatalogs.item(i)).getAttribute("uri"); + for (int i = 0; i < catalogElements.getLength(); i++) { + final String uriAttributeValue = ((Element) catalogElements.item(i)).getAttribute("uri"); if (!uriAttributeValue.isEmpty()) { final String uri; @@ -1246,20 +1291,7 @@ private void configureValidation(final Optional dbHome, final Element vali catalogUris.add(uri); } } - - // Store all configured URIs - setProperty(XMLReaderObjectFactory.CATALOG_URIS, catalogUris); - - // Create and Store the resolver - try { - final List>> catalogs = catalogUris.stream() - .map(catalogUri -> Tuple(catalogUri, Optional.empty())) - .toList(); - final Resolver resolver = ResolverFactory.newResolver(catalogs); - setProperty(XMLReaderObjectFactory.CATALOG_RESOLVER, resolver); - } catch (final URISyntaxException e) { - LOG.error("Unable to parse catalog uri: {}", e.getMessage(), e); - } + return catalogUris; } private void configureRpcServer(final Element validation) throws DatabaseConfigurationException { diff --git a/exist-core/src/main/java/org/exist/util/XMLReaderObjectFactory.java b/exist-core/src/main/java/org/exist/util/XMLReaderObjectFactory.java index b28677e9c55..b280122a584 100644 --- a/exist-core/src/main/java/org/exist/util/XMLReaderObjectFactory.java +++ b/exist-core/src/main/java/org/exist/util/XMLReaderObjectFactory.java @@ -60,7 +60,6 @@ public class XMLReaderObjectFactory extends BasePooledObjectFactory i public static final String PROPERTY_VALIDATION_MODE = "validation.mode"; public static final String CATALOG_RESOLVER = "validation.resolver"; public static final String CATALOG_URIS = "validation.catalog_uris"; - public static final String GRAMMAR_POOL = "validation.grammar_pool"; // Xerces feature and property names public static final String APACHE_FEATURES_VALIDATION_SCHEMA @@ -83,7 +82,7 @@ public class XMLReaderObjectFactory extends BasePooledObjectFactory i @Override public void configure(final Configuration configuration) { - this.grammarPool = (GrammarPool) configuration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL); + this.grammarPool = (GrammarPool) configuration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT); this.resolver = (Resolver) configuration.getProperty(CATALOG_RESOLVER); final String option = (String) configuration.getProperty(PROPERTY_VALIDATION_MODE); this.validation = VALIDATION_SETTING.fromOption(option); diff --git a/exist-core/src/main/java/org/exist/validation/GrammarPool.java b/exist-core/src/main/java/org/exist/validation/GrammarPool.java index a57ebcc8564..0529d1e27a4 100644 --- a/exist-core/src/main/java/org/exist/validation/GrammarPool.java +++ b/exist-core/src/main/java/org/exist/validation/GrammarPool.java @@ -21,186 +21,147 @@ */ package org.exist.validation; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.xerces.util.XMLGrammarPoolImpl; import org.apache.xerces.xni.grammars.Grammar; import org.apache.xerces.xni.grammars.XMLGrammarDescription; import org.apache.xerces.xni.grammars.XMLGrammarPool; -import org.exist.Namespaces; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.TimeUnit; /** - * Wrapper around the Xerces XMLGrammarPoolImpl, so debugging of - * actions can be monitored. Javadoc copied from xml.apache.org. - * - * @author Dannes Wessels (dizzzz@exist-db.org) - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool - * @see org.apache.xerces.util.XMLGrammarPoolImpl - * @see org.apache.xerces.xni.grammars.Grammar - * @see org.apache.xerces.xni.grammars.XMLGrammarDescription + * Smart grammar-cache for xerces based on the Caffeine library. */ public class GrammarPool implements XMLGrammarPool { - - private final static Logger logger = LogManager.getLogger(GrammarPool.class); - - private final XMLGrammarPool pool; - + + private static final Logger LOGGER = LogManager.getLogger(GrammarPool.class); + + public static final String GRAMMAR_POOL_ELEMENT = "grammar-cache"; + + public static final String ATTRIBUTE_MAXIMUM_SIZE = "size"; + public static final String PROPERTY_MAXIMUM_SIZE = "validation.grammar-cache.size"; + + public static final String ATTRIBUTE_EXPIRE_AFTER_ACCESS = "expire"; + public static final String PROPERTY_EXPIRE_AFTER_ACCESS = "validation.grammar-cache.expire"; + + private final Cache grammarCache; + private boolean isLocked = false; + /** - * Constructs a grammar pool with a default number of buckets. + * Constructor. Default 128 entries, lifetime after last access is 60 minutes. */ public GrammarPool() { - if (logger.isInfoEnabled()) - {logger.info("Initializing GrammarPool.");} - pool = new XMLGrammarPoolImpl(); - } - - /** - * Constructs a grammar pool with a default number of buckets using pool. - * - * @param pool The supplied grammar pool is reused. - */ - public GrammarPool(XMLGrammarPool pool) { - if (logger.isInfoEnabled()) - {logger.info("Initializing GrammarPool using supplied pool.");} - this.pool=pool; - } - - /** - * Retrieve the initial known set of grammars. this method is called - * by a validator before the validation starts. the application can provide - * an initial set of grammars available to the current validation attempt. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#retrieveInitialGrammarSet(String) - * - * @param type The type of the grammar, from the - * org.apache.xerces.xni.grammars.Grammar interface. - * @return The set of grammars the validator may put in its "bucket" - */ - public Grammar[] retrieveInitialGrammarSet(String type) { - if (logger.isDebugEnabled()) - { - logger.debug("Retrieve initial grammarset ({}).", type);} - - final Grammar[] grammars = pool.retrieveInitialGrammarSet(type); - if (logger.isDebugEnabled()) - { - logger.debug("Found {} grammars.", grammars.length);} - return grammars; - } - - /** - * Return the final set of grammars that the validator ended up with. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#cacheGrammars(String,Grammar[]) - * - * @param type The type of the grammars being returned - * @param grammar an array containing the set of grammars being - * returned; order is not significant. - */ - public void cacheGrammars(String type, Grammar[] grammar) { - if (logger.isDebugEnabled()) - { - logger.debug("Cache {} grammars ({}).", grammar.length, type);} - pool.cacheGrammars(type, grammar); - } - - /** - * Allows the XMLGrammarPool to store grammars when its - * cacheGrammars(String, Grammar[]) method is called. This is the default - * state of the object. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#unlockPool - */ - public void unlockPool() { - if (logger.isDebugEnabled()) - {logger.debug("Unlock grammarpool.");} - pool.unlockPool(); + this(-1, -1L); } - + /** - * This method requests that the application retrieve a grammar - * corresponding to the given GrammarIdentifier from its cache. If it - * cannot do so it must return null; the parser will then call the - * EntityResolver. An application must not call its EntityResolver itself - * from this method; this may result in infinite recursions. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#retrieveGrammar(XMLGrammarDescription) + * Constructor. * - * @param xgd The description of the Grammar being requested. - * @return the Grammar corresponding to this description or null - * if no such Grammar is known. + * @param maxSize Maximum nr of cached elements. + * @param seconds Maximum expiration time in seconds after last access. */ - public Grammar retrieveGrammar(XMLGrammarDescription xgd) { + public GrammarPool(final long maxSize, final long seconds) { - if (xgd == null) { - if (logger.isDebugEnabled()) { - logger.debug("XMLGrammarDescription is null"); - } - return null; + Caffeine cafeineBuilder = Caffeine.newBuilder(); + + if (maxSize > 0) { + cafeineBuilder = cafeineBuilder.maximumSize(maxSize); } - if (xgd.getNamespace() != null) { - if (logger.isDebugEnabled()) { - logger.debug("Retrieve grammar for namespace '{}'.", xgd.getNamespace()); - } + if (seconds > 0L) { + cafeineBuilder.expireAfterAccess(seconds, TimeUnit.SECONDS); } - if (xgd.getPublicId() != null) { - if (logger.isDebugEnabled()) { - logger.debug("Retrieve grammar for publicId '{}'.", xgd.getPublicId()); + final String sizeTxt =maxSize > 0 ? String.valueOf(maxSize) : "unlimited"; + final String expireTxt = seconds > 0L ? seconds + " seconds" : "infinite"; + + final Level level = seconds > 0L && maxSize > 0 ? Level.INFO : Level.WARN; + LOGGER.log(level, "Grammar cache: size={}, lifetime={}", sizeTxt, expireTxt); + + grammarCache = cafeineBuilder.build(); + } + + @Override + public Grammar[] retrieveInitialGrammarSet(final String grammarType) { + final List grammars = new ArrayList<>(); + grammarCache.asMap().forEach((key, value) -> { + if (key.grammarType.equals(grammarType)) { + grammars.add(value); } - } + }); + return grammars.toArray(new Grammar[0]); + } + + @Override + public void cacheGrammars(final String grammarType, final Grammar[] grammars) { + if (isLocked || grammars == null) return; - return pool.retrieveGrammar(xgd); + Arrays.stream(grammars).forEach(grammar -> { + final XMLGrammarDescription desc = grammar.getGrammarDescription(); + grammarCache.put(new GrammarKey(desc), grammar); + }); } - - /** - * Causes the XMLGrammarPool not to store any grammars when the - * cacheGrammars(String, Grammar[[]) method is called. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#lockPool - */ + + @Override + public Grammar retrieveGrammar(final XMLGrammarDescription desc) { + return grammarCache.getIfPresent(new GrammarKey(desc)); + } + + @Override public void lockPool() { - if (logger.isDebugEnabled()) - {logger.debug("Lock grammarpool.");} - pool.lockPool(); + isLocked = true; } - - /** - * Removes all grammars from the pool. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#clear - */ + + @Override + public void unlockPool() { + isLocked = false; + } + + @Override public void clear() { - if (logger.isDebugEnabled()) - {logger.debug("Clear grammarpool.");} - pool.clear(); + if (isLocked) return; + + grammarCache.invalidateAll(); } - - /** - * Removes all DTD grammars from the pool. Workaround for Xerces bug. - * - * @see org.apache.xerces.xni.grammars.XMLGrammarPool#clear - */ - public void clearDTDs() { - //if (logger.isDebugEnabled()) - // logger.debug("Removing DTD's from grammarpool."); - - final Grammar dtds[] = retrieveInitialGrammarSet(Namespaces.DTD_NS); - if (dtds.length > 0) { - if (logger.isDebugEnabled()) { - logger.debug("Removing {} DTDs.", dtds.length); - } - final Grammar schemas[] = retrieveInitialGrammarSet(Namespaces.SCHEMA_NS); - clear(); - cacheGrammars(Namespaces.SCHEMA_NS, schemas); - - } else { - //if (logger.isDebugEnabled()) - // logger.debug("No DTDs to be removed."); + + @Override + public String toString() { + return grammarCache.stats().toString(); + } + + // Helper class for cache keys + private static class GrammarKey { + private final String grammarType; + private final String targetNamespace; + + public GrammarKey(final XMLGrammarDescription desc) { + this.grammarType = desc.getGrammarType(); + this.targetNamespace = desc.getNamespace(); + } + + @Override + public int hashCode() { + return Objects.hash(grammarType, targetNamespace); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) return true; + if (!(obj instanceof final GrammarKey other)) return false; + return Objects.equals(grammarType, other.grammarType) && + Objects.equals(targetNamespace, other.targetNamespace); + } + + @Override + public String toString() { + return "grammarType='%s', targetNamespace='%s'".formatted(grammarType, targetNamespace); } } - - } diff --git a/exist-core/src/main/java/org/exist/validation/ValidationContentHandler.java b/exist-core/src/main/java/org/exist/validation/ValidationContentHandler.java index 8b40c5c94bb..a1a2101e531 100644 --- a/exist-core/src/main/java/org/exist/validation/ValidationContentHandler.java +++ b/exist-core/src/main/java/org/exist/validation/ValidationContentHandler.java @@ -27,36 +27,36 @@ import org.xml.sax.helpers.DefaultHandler; /** - * Simple contenthandler to determine the NamespaceUri of + * Simple contenthandler to determine the NamespaceUri of * the document root node. - * + * * @author Dannes Wessels */ public class ValidationContentHandler extends DefaultHandler { private boolean isFirstElement = true; private String namespaceUri = null; - - + + /** - * @see org.xml.sax.helpers.DefaultHandler#startElement(String,String,String,Attributes) + * @see org.xml.sax.helpers.DefaultHandler#startElement(String, String, String, Attributes) */ @Override - public void startElement(String uri, String localName, String qName, - Attributes attributes) throws SAXException { - - if(isFirstElement){ - namespaceUri=uri; - isFirstElement=false; + public void startElement(final String uri, final String localName, final String qName, + final Attributes attributes) throws SAXException { + + if (isFirstElement) { + namespaceUri = uri; + isFirstElement = false; } } - + /** - * Get namespace of root element. To be used for reporting. - * + * Get namespace of root element. To be used for reporting. + * * @return Namespace of root element. */ - public String getNamespaceUri(){ + public String getNamespaceUri() { return namespaceUri; } } \ No newline at end of file diff --git a/exist-core/src/main/java/org/exist/validation/ValidationReport.java b/exist-core/src/main/java/org/exist/validation/ValidationReport.java index e1797e920a6..116d3cca709 100644 --- a/exist-core/src/main/java/org/exist/validation/ValidationReport.java +++ b/exist-core/src/main/java/org/exist/validation/ValidationReport.java @@ -21,39 +21,37 @@ */ package org.exist.validation; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; - import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + import static java.nio.charset.StandardCharsets.UTF_8; /** * Report containing all validation info (errors, warnings). * * @author Dannes Wessels (dizzzz@exist-db.org) - * * @see org.xml.sax.ErrorHandler */ public class ValidationReport implements ErrorHandler { - + private final List validationReport = new ArrayList<>(); - + private ValidationReportItem lastItem; - + private long duration = -1L; private long start = -1L; private Throwable throwed = null; private String namespaceUri = null; - - private ValidationReportItem createValidationReportItem(int type, SAXParseException exception){ - + + private ValidationReportItem createValidationReportItem(final int type, final SAXParseException exception) { + final ValidationReportItem vri = new ValidationReportItem(); vri.setType(type); vri.setLineNumber(exception.getLineNumber()); @@ -63,17 +61,17 @@ private ValidationReportItem createValidationReportItem(int type, SAXParseExcept vri.setSystemId(exception.getSystemId()); return vri; } - - private void addItem(ValidationReportItem newItem) { + + private void addItem(final ValidationReportItem newItem) { if (lastItem == null) { // First reported item validationReport.add(newItem); lastItem = newItem; - + } else if (lastItem.getMessage().equals(newItem.getMessage())) { // Message is repeated lastItem.increaseRepeat(); - + } else { // Received new message validationReport.add(newItem); @@ -82,143 +80,144 @@ private void addItem(ValidationReportItem newItem) { lastItem = newItem; } } - + /** - * Receive notification of a recoverable error. + * Receive notification of a recoverable error. + * * @param exception The warning information encapsulated in a - * SAX parse exception. + * SAX parse exception. * @throws SAXException Any SAX exception, possibly wrapping another * exception. */ - public void error(SAXParseException exception) throws SAXException { - addItem( createValidationReportItem(ValidationReportItem.ERROR, exception) ); + public void error(final SAXParseException exception) throws SAXException { + addItem(createValidationReportItem(ValidationReportItem.ERROR, exception)); } - + /** - * Receive notification of a non-recoverable error. + * Receive notification of a non-recoverable error. * - * @param exception The warning information encapsulated in a - * SAX parse exception. + * @param exception The warning information encapsulated in a + * SAX parse exception. * @throws SAXException Any SAX exception, possibly wrapping another * exception. */ - public void fatalError(SAXParseException exception) throws SAXException { - addItem( createValidationReportItem(ValidationReportItem.FATAL, exception) ); + public void fatalError(final SAXParseException exception) throws SAXException { + addItem(createValidationReportItem(ValidationReportItem.FATAL, exception)); } - + /** * Receive notification of a warning. * - * @param exception The warning information encapsulated in a - * SAX parse exception. + * @param exception The warning information encapsulated in a + * SAX parse exception. * @throws SAXException Any SAX exception, possibly wrapping another * exception. */ - public void warning(SAXParseException exception) throws SAXException { - addItem( createValidationReportItem(ValidationReportItem.WARNING, exception) ); + public void warning(final SAXParseException exception) throws SAXException { + addItem(createValidationReportItem(ValidationReportItem.WARNING, exception)); } - - - public void setException(Throwable ex){ - this.throwed=ex; + + + public void setException(final Throwable ex) { + this.throwed = ex; } - + /** - * Give validation information of the XML document. + * Give validation information of the XML document. * * @return FALSE if no errors and warnings occurred. */ - public boolean isValid(){ + public boolean isValid() { return (validationReport.isEmpty() && (throwed == null)); } - - public List getValidationReportItemList(){ + + public List getValidationReportItemList() { return validationReport; } - - public List getTextValidationReport(){ - + + public List getTextValidationReport() { + final List textReport = new ArrayList<>(); - - if( isValid() ){ + + if (isValid()) { textReport.add("Document is valid."); } else { textReport.add("Document is not valid."); } - - if(throwed!=null){ - textReport.add( "Exception: " + throwed.getMessage() ); + + if (throwed != null) { + textReport.add("Exception: " + throwed.getMessage()); } - textReport.addAll(validationReport.stream().map(ValidationReportItem::toString).collect(Collectors.toList())); + textReport.addAll(validationReport.stream().map(ValidationReportItem::toString).toList()); - textReport.add("Validated in "+duration+" millisec."); + textReport.add("Validated in " + duration + " millisec."); return textReport; } - - public String[] getValidationReportArray(){ - + + public String[] getValidationReportArray() { + final List vr = getTextValidationReport(); - final String report[] = new String[ vr.size() ]; - + final String[] report = new String[vr.size()]; + return vr.toArray(report); } - - public void setValidationDuration(long time) { - duration=time; - } - + public long getValidationDuration() { return duration; } - + + public void setValidationDuration(final long time) { + duration = time; + } + @Override - public String toString(){ - - final StringBuilder sb = new StringBuilder(); + public String toString() { + + final StringBuilder sb = new StringBuilder(); - for(final String line : getTextValidationReport()){ + for (final String line : getTextValidationReport()) { sb.append(line); sb.append("\n"); } - + return sb.toString(); } public void start() { - start=System.currentTimeMillis(); + start = System.currentTimeMillis(); } public void stop() { - if(getValidationDuration() == -1L){ // not already stopped - long stop = System.currentTimeMillis(); - setValidationDuration(stop -start); + if (getValidationDuration() == -1L) { // not already stopped + final long stop = System.currentTimeMillis(); + setValidationDuration(stop - start); } } - public void setThrowable(Throwable throwable) { - throwed=throwable; - } - public Throwable getThrowable() { return throwed; } - - public void setNamespaceUri(String namespace){ - namespaceUri=namespace; + + public void setThrowable(final Throwable throwable) { + throwed = throwable; } - - public String getNamespaceUri(){ + + public String getNamespaceUri() { return namespaceUri; } + public void setNamespaceUri(final String namespace) { + namespaceUri = namespace; + } + public String getStackTrace() { if (throwed == null) { return null; } - final UnsynchronizedByteArrayOutputStream baos = new UnsynchronizedByteArrayOutputStream(); + final UnsynchronizedByteArrayOutputStream baos = UnsynchronizedByteArrayOutputStream.builder().get(); final PrintStream ps = new PrintStream(baos); throwed.printStackTrace(ps); return baos.toString(UTF_8); diff --git a/exist-core/src/main/java/org/exist/validation/ValidationReportItem.java b/exist-core/src/main/java/org/exist/validation/ValidationReportItem.java index 2f3a91d8ee6..95cbdd4a9fa 100644 --- a/exist-core/src/main/java/org/exist/validation/ValidationReportItem.java +++ b/exist-core/src/main/java/org/exist/validation/ValidationReportItem.java @@ -25,92 +25,90 @@ * Helper class for validation (error) messages. */ public class ValidationReportItem { - + public static final int WARNING = 1; public static final int ERROR = 2; public static final int FATAL = 4; - + private int type = -1; private int lineNumber = -1; private int columnNumber = -1; private String publicId = null; - private String systemId = null; - private String message =""; - private int repeat=1; - - public void setType(int type){ - this.type=type; - } - - public int getType(){ + private String systemId = null; + private String message = ""; + private int repeat = 1; + + public int getType() { return type; } - - public void setLineNumber(int nr){ - this.lineNumber=nr; + + public void setType(final int type) { + this.type = type; } - - public int getLineNumber(){ + + public int getLineNumber() { return this.lineNumber; } - - public void setColumnNumber(int nr){ - this.columnNumber=nr; + + public void setLineNumber(final int nr) { + this.lineNumber = nr; } - - public int getColumnNumber(){ + + public int getColumnNumber() { return this.columnNumber; } - - public void setMessage(String message){ - this.message=message; + + public void setColumnNumber(final int nr) { + this.columnNumber = nr; } - - public String getMessage(){ + + public String getMessage() { return this.message; } - - public void setPublicId(String publicId){ - this.publicId=publicId; + + public void setMessage(final String message) { + this.message = message; } - - public String getPublicId(){ + + public String getPublicId() { return this.publicId; } - - public void setSystemId(String systemId){ - this.systemId=systemId; + + public void setPublicId(final String publicId) { + this.publicId = publicId; } - - public String getSystemId(){ + + public String getSystemId() { return this.systemId; } - + + public void setSystemId(final String systemId) { + this.systemId = systemId; + } + public String getTypeText() { - String reportType = switch (type) { + return switch (type) { case WARNING -> "Warning"; case ERROR -> "Error"; case FATAL -> "Fatal"; default -> "Unknown Error type"; }; - - return reportType; } - - public String toString(){ - - final String reportType=getTypeText(); - + + public String toString() { + + final String reportType = getTypeText(); + return (reportType - + " (" + lineNumber +","+ columnNumber + ") : " + message); + + " (" + lineNumber + "," + columnNumber + ") : " + message); } - - public void increaseRepeat(){ + + public void increaseRepeat() { repeat++; } - - public int getRepeat(){ + + public int getRepeat() { return repeat; } } diff --git a/exist-core/src/main/java/org/exist/validation/Validator.java b/exist-core/src/main/java/org/exist/validation/Validator.java index e225664ceb6..4766bfbc8d0 100644 --- a/exist-core/src/main/java/org/exist/validation/Validator.java +++ b/exist-core/src/main/java/org/exist/validation/Validator.java @@ -26,15 +26,6 @@ import com.thaiopensource.validate.ValidateProperty; import com.thaiopensource.validate.ValidationDriver; import com.thaiopensource.validate.rng.CompactSchemaReader; -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Optional; -import javax.annotation.Nullable; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.xerces.xni.parser.XMLEntityResolver; @@ -48,18 +39,24 @@ import org.exist.util.XMLReaderObjectFactory; import org.exist.validation.resolver.AnyUriResolver; import org.exist.validation.resolver.SearchResourceResolver; -import org.xml.sax.ContentHandler; -import org.xml.sax.ErrorHandler; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; +import org.xml.sax.*; import org.xmlresolver.Resolver; +import javax.annotation.Nullable; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Optional; + import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple; import static javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING; /** - * Validate XML documents with their grammars (DTD's and Schemas). + * Validate XML documents with their grammars (DTD's and Schemas). * * @author Dannes Wessels (dizzzz@exist-db.org) */ @@ -74,9 +71,9 @@ public class Validator { /** * Setup Validator object with Broker Pool as db connection. - * + * * @param brokerPool brokerPool the broker pool - * @param subject the subject to use when accessing resources from the database + * @param subject the subject to use when accessing resources from the database */ public Validator(final BrokerPool brokerPool, final Subject subject) { logger.info("Initializing Validator."); @@ -93,28 +90,28 @@ public Validator(final BrokerPool brokerPool, final Subject subject) { final Configuration config = brokerPool.getConfiguration(); // setup grammar brokerPool - this.grammarPool = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL); + this.grammarPool = (GrammarPool) config.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT); // setup system wide catalog resolver this.systemCatalogResolver = (Resolver) config.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER); } - + /** - * Validate XML data using system catalog. XSD and DTD only. + * Validate XML data using system catalog. XSD and DTD only. * * @param stream XML input. * @return Validation report containing all validation info. */ - public ValidationReport validate(InputStream stream) { + public ValidationReport validate(final InputStream stream) { return validate(stream, null); } - + /** - * Validate XML data from reader using specified grammar. + * Validate XML data from reader using specified grammar. * - * @param grammarUrl User supplied path to grammar, or null. - * @param stream XML input. + * @param grammarUrl User supplied path to grammar, or null. + * @param stream XML input. * @return Validation report containing all validation info. */ public ValidationReport validate(final InputStream stream, @Nullable String grammarUrl) { @@ -126,10 +123,10 @@ public ValidationReport validate(final InputStream stream, @Nullable String gram if (grammarUrl != null && (grammarUrl.endsWith(".rng") || grammarUrl.endsWith(".rnc") || - grammarUrl.endsWith(".nvdl") || grammarUrl.endsWith(".sch"))) { + grammarUrl.endsWith(".nvdl") || grammarUrl.endsWith(".sch"))) { // Validate with Jing return validateJing(stream, grammarUrl); - + } else { // Validate with Xerces return validateParse(stream, grammarUrl); @@ -138,13 +135,13 @@ public ValidationReport validate(final InputStream stream, @Nullable String gram } /** - * Validate XML data from reader using specified grammar with Jing. + * Validate XML data from reader using specified grammar with Jing. * - * @param stream XML input document. - * @param grammarUrl User supplied path to grammar. + * @param stream XML input document. + * @param grammarUrl User supplied path to grammar. * @return Validation report containing all validation info. */ - public ValidationReport validateJing(InputStream stream, String grammarUrl) { + public ValidationReport validateJing(final InputStream stream, final String grammarUrl) { final ValidationReport report = new ValidationReport(); try { @@ -167,11 +164,11 @@ public ValidationReport validateJing(InputStream stream, String grammarUrl) { // Validate XML instance driver.validate(new InputSource(stream)); - } catch(final IOException ex) { + } catch (final IOException ex) { logger.error(ex); report.setThrowable(ex); - } catch(final SAXException ex) { + } catch (final SAXException ex) { logger.debug(ex); report.setThrowable(ex); @@ -182,23 +179,23 @@ public ValidationReport validateJing(InputStream stream, String grammarUrl) { } /** - * Validate XML data using system catalog. XSD and DTD only. + * Validate XML data using system catalog. XSD and DTD only. * * @param stream XML input. * @return Validation report containing all validation info. */ - public ValidationReport validateParse(InputStream stream) { + public ValidationReport validateParse(final InputStream stream) { return validateParse(stream, null); } /** - * Validate XML data from reader using specified grammar. + * Validate XML data from reader using specified grammar. * - * @param grammarUrl User supplied path to grammar. - * @param stream XML input. + * @param grammarUrl User supplied path to grammar. + * @param stream XML input. * @return Validation report containing all validation info. */ - public ValidationReport validateParse(InputStream stream, String grammarUrl) { + public ValidationReport validateParse(final InputStream stream, String grammarUrl) { logger.debug("Start validation."); @@ -223,7 +220,7 @@ public ValidationReport validateParse(InputStream stream, String grammarUrl) { if (logger.isDebugEnabled()) { logger.debug("Validation using user specified catalog '{}'.", grammarUrl); } - final Resolver resolver = ResolverFactory.newResolver(Arrays.asList(Tuple(grammarUrl, Optional.empty()))); + final Resolver resolver = ResolverFactory.newResolver(List.of(Tuple(grammarUrl, Optional.empty()))); XercesXmlResolverAdapter.setXmlReaderEntityResolver(xmlReader, resolver); } else if (grammarUrl.endsWith("/")) { @@ -265,7 +262,7 @@ public ValidationReport validateParse(InputStream stream, String grammarUrl) { logger.debug("Document is not valid."); } - } catch(final ParserConfigurationException | SAXException | IOException | URISyntaxException ex) { + } catch (final ParserConfigurationException | SAXException | IOException | URISyntaxException ex) { logger.error(ex); report.setThrowable(ex); @@ -279,8 +276,8 @@ public ValidationReport validateParse(InputStream stream, String grammarUrl) { return report; } - private XMLReader getXMLReader(ContentHandler contentHandler, - ErrorHandler errorHandler) throws ParserConfigurationException, SAXException { + private XMLReader getXMLReader(final ContentHandler contentHandler, + final ErrorHandler errorHandler) throws ParserConfigurationException, SAXException { // setup sax factory ; be sure just one instance! final SAXParserFactory saxFactory = ExistSAXParserFactory.getSAXParserFactory(); diff --git a/exist-core/src/main/java/org/exist/validation/XmlLibraryChecker.java b/exist-core/src/main/java/org/exist/validation/XmlLibraryChecker.java index 31f2fbf6479..5b9a570f3f3 100644 --- a/exist-core/src/main/java/org/exist/validation/XmlLibraryChecker.java +++ b/exist-core/src/main/java/org/exist/validation/XmlLibraryChecker.java @@ -21,22 +21,23 @@ */ package org.exist.validation; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ServiceLoader; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParserFactory; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerFactory; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.exist.util.ExistSAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ServiceLoader; + /** - * Class for checking dependencies with XML libraries. + * Class for checking dependencies with XML libraries. * * @author Adam Retter */ @@ -46,33 +47,33 @@ public class XmlLibraryChecker { * Possible XML Parsers, at least one must be valid */ private final static ClassVersion[] validParsers = { - new ClassVersion("Xerces", "Xerces-J 2.10.0", "org.apache.xerces.impl.Version.getVersion()") + new ClassVersion("Xerces", "Xerces-J 2.10.0", "org.apache.xerces.impl.Version.getVersion()") }; - + /** * Possible XML Transformers, at least one must be valid */ private final static ClassVersion[] validTransformers = { - new ClassVersion("Saxon", "8.9.0", "net.sf.saxon.Version.getProductVersion()"), - new ClassVersion("Xalan", "Xalan Java 2.7.1", "org.apache.xalan.Version.getVersion()"), + new ClassVersion("Saxon", "8.9.0", "net.sf.saxon.Version.getProductVersion()"), + new ClassVersion("Xalan", "Xalan Java 2.7.1", "org.apache.xalan.Version.getVersion()"), }; - + /** * Possible XML resolvers, at least one must be valid */ private final static ClassVersion[] validResolvers = { - new ClassVersion("Resolver", "XmlResolver 1.2", "org.apache.xml.resolver.Version.getVersion()"), + new ClassVersion("Resolver", "XmlResolver 1.2", "org.apache.xml.resolver.Version.getVersion()"), }; - - - private final static Logger logger = LogManager.getLogger( XmlLibraryChecker.class ); + + + private final static Logger logger = LogManager.getLogger(XmlLibraryChecker.class); /** - * Remove "@" from string. + * Remove "@" from string. */ - private static String getClassName(String classid) { - String className; + private static String getClassName(final String classid) { + final String className; final int lastChar = classid.lastIndexOf('@'); if (lastChar == -1) { @@ -84,8 +85,8 @@ private static String getClassName(String classid) { } /** - * Determine the class that is actually used as XML parser. - * + * Determine the class that is actually used as XML parser. + * * @return Full classname of parser. */ private static String determineActualParserClass() { @@ -96,20 +97,20 @@ private static String determineActualParserClass() { final XMLReader xmlReader = factory.newSAXParser().getXMLReader(); final String classId = xmlReader.toString(); parserClass = getClassName(classId); - + } catch (final ParserConfigurationException | SAXException ex) { logger.error(ex.getMessage()); } return parserClass; } - + /** - * Determine the class that is actually used as XML transformer. - * + * Determine the class that is actually used as XML transformer. + * * @return Full classname of transformer. */ - private static String determineActualTransformerClass(){ + private static String determineActualTransformerClass() { String transformerClass = "Unable to determine transformer class"; try { final TransformerFactory factory = TransformerFactory.newInstance(); @@ -120,11 +121,11 @@ private static String determineActualTransformerClass(){ } catch (final TransformerConfigurationException ex) { logger.error(ex.getMessage()); } - return transformerClass; + return transformerClass; } /** - * Perform checks on parsers, transformers and resolvers. + * Perform checks on parsers, transformers and resolvers. */ public static void check() { @@ -134,22 +135,22 @@ public static void check() { * Parser */ final ServiceLoader allSax = ServiceLoader.load(SAXParserFactory.class); - for(final SAXParserFactory sax : allSax){ + for (final SAXParserFactory sax : allSax) { message.append(getClassName(sax.toString())); message.append(" "); } logger.debug("Detected SAXParserFactory classes: {}", message.toString()); - + message = new StringBuilder(); - boolean invalidVersionFound = false; + boolean invalidVersionFound = false; - if( hasValidClassVersion( "Parser", validParsers, message ) ) { - logger.info( message.toString() ); + if (hasValidClassVersion("Parser", validParsers, message)) { + logger.info(message.toString()); } else { - logger.warn(message.toString()); - invalidVersionFound = true; + logger.warn(message.toString()); + invalidVersionFound = true; } /* @@ -158,56 +159,56 @@ public static void check() { message = new StringBuilder(); final ServiceLoader allXsl = ServiceLoader.load(TransformerFactory.class); - for(final TransformerFactory xsl : allXsl){ + for (final TransformerFactory xsl : allXsl) { message.append(getClassName(xsl.toString())); message.append(" "); } logger.debug("Detected TransformerFactory classes: {}", message.toString()); - + message = new StringBuilder(); - if( hasValidClassVersion( "Transformer", validTransformers, message ) ) { - logger.info( message.toString() ); + if (hasValidClassVersion("Transformer", validTransformers, message)) { + logger.info(message.toString()); } else { - logger.warn( message.toString() ); + logger.warn(message.toString()); System.err.println(message); - invalidVersionFound = true; + invalidVersionFound = true; } /* * Resolver */ message = new StringBuilder(); - if( hasValidClassVersion( "Resolver", validResolvers, message ) ) { + if (hasValidClassVersion("Resolver", validResolvers, message)) { logger.info(message.toString()); } else { logger.warn(message.toString()); - invalidVersionFound = true; + invalidVersionFound = true; } logger.info("Using parser {}", determineActualParserClass()); logger.info("Using transformer {}", determineActualTransformerClass()); - - if(invalidVersionFound) { + + if (invalidVersionFound) { logger.warn("Using parser {}", determineActualParserClass()); logger.warn("Using transformer {}", determineActualTransformerClass()); - } + } } /** - * Check if for the specified service object one of the required + * Check if for the specified service object one of the required * classes is available. - * - * @param type Parser, Transformer or Resolver, used for reporting only. - * @param validClasses Array of valid classes. - * @param message Output message of detecting classes. + * + * @param type Parser, Transformer or Resolver, used for reporting only. + * @param validClasses Array of valid classes. + * @param message Output message of detecting classes. * @return TRUE if valid class has been found, otherwise FALSE. */ - public static boolean hasValidClassVersion(String type, - ClassVersion[] validClasses, StringBuilder message) { + public static boolean hasValidClassVersion(final String type, + final ClassVersion[] validClasses, final StringBuilder message) { - final String sep = System.getProperty("line.separator"); + final String sep = System.lineSeparator(); message.append("Looking for a valid ").append(type).append("...").append(sep); @@ -220,13 +221,13 @@ public static boolean hasValidClassVersion(String type, message.append(", found version ").append(actualVersion); if (actualVersion.compareToIgnoreCase( - validClass.getRequiredVersion()) >= 0) { + validClass.getRequiredVersion()) >= 0) { message.append(sep).append("OK!").append(sep); return true; } else { message.append(" needed version ").append(validClass.getRequiredVersion()).append(sep); } - + } else { message.append(", not found!").append(sep); } @@ -234,8 +235,8 @@ public static boolean hasValidClassVersion(String type, message.append("Warning: Failed find a valid ").append(type).append("!").append(sep); message.append(sep).append("Please add an appropriate ").append(type) - .append(" to the " + "class-path, e.g. in the 'endorsed' folder of " - + "the servlet container or in the 'endorsed' folder of the JRE.") + .append(" to the " + "class-path, e.g. in the 'endorsed' folder of " + + "the servlet container or in the 'endorsed' folder of the JRE.") .append(sep); return false; @@ -243,7 +244,7 @@ public static boolean hasValidClassVersion(String type, /** * Checks to see if a valid XML Parser exists - * + * * @return boolean true indicates a valid Parser was found, false otherwise */ public static boolean hasValidParser() { @@ -252,21 +253,20 @@ public static boolean hasValidParser() { /** * Checks to see if a valid XML Parser exists - * - * @param message Messages about the status of available Parser's will - * be appended to this buffer - * + * + * @param message Messages about the status of available Parser's will + * be appended to this buffer * @return boolean true indicates a valid Parser was found, false otherwise */ - public static boolean hasValidParser(StringBuilder message) { + public static boolean hasValidParser(final StringBuilder message) { return hasValidClassVersion("Parser", validParsers, message); } /** * Checks to see if a valid XML Transformer exists - * - * @return boolean true indicates a valid Transformer was found, - * false otherwise + * + * @return boolean true indicates a valid Transformer was found, + * false otherwise */ public static boolean hasValidTransformer() { return hasValidTransformer(new StringBuilder()); @@ -274,20 +274,19 @@ public static boolean hasValidTransformer() { /** * Checks to see if a valid XML Transformer exists - * - * @param message Messages about the status of available Transformer's - * will be appended to this buffer - * - * @return boolean true indicates a valid Transformer was found, - * false otherwise + * + * @param message Messages about the status of available Transformer's + * will be appended to this buffer + * @return boolean true indicates a valid Transformer was found, + * false otherwise */ - public static boolean hasValidTransformer(StringBuilder message) { + public static boolean hasValidTransformer(final StringBuilder message) { return hasValidClassVersion("Transformer", validTransformers, message); } /** - * Simple class to describe a class, its required version and how to - * obtain the actual version + * Simple class to describe a class, its required version and how to + * obtain the actual version */ public static class ClassVersion { @@ -297,39 +296,39 @@ public static class ClassVersion { /** * Default Constructor - * - * @param simpleName The simple name for the class (just a - * descriptor really) - * @param requiredVersion The required version of the class - * @param versionFunction The function to be invoked to obtain the - * actual version of the class, must be fully - * qualified (i.e. includes the package name) + * + * @param simpleName The simple name for the class (just a + * descriptor really) + * @param requiredVersion The required version of the class + * @param versionFunction The function to be invoked to obtain the + * actual version of the class, must be fully + * qualified (i.e. includes the package name) */ - ClassVersion(String simpleName, String requiredVersion, String versionFunction) { + ClassVersion(final String simpleName, final String requiredVersion, final String versionFunction) { this.simpleName = simpleName; this.requiredVersion = requiredVersion; this.versionFunction = versionFunction; } /** - * @return the simple name of the class + * @return the simple name of the class */ public String getSimpleName() { return simpleName; } /** - * @return the required version of the class + * @return the required version of the class */ public String getRequiredVersion() { return requiredVersion; } /** - * Invokes the specified versionFunction using reflection to get the + * Invokes the specified versionFunction using reflection to get the * actual version of the class - * - * @return the actual version of the class + * + * @return the actual version of the class */ public String getActualVersion() { String actualVersion = null; @@ -351,8 +350,9 @@ public String getActualVersion() { //invoke the method on the class actualVersion = (String) getVersionMethod.invoke(versionClass, (Object[]) null); - - } catch (final ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + + } catch (final ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | + IllegalArgumentException | InvocationTargetException ex) { logger.debug(ex.getMessage()); } diff --git a/exist-core/src/main/java/org/exist/validation/internal/DatabaseResources.java b/exist-core/src/main/java/org/exist/validation/internal/DatabaseResources.java index 7a58ebdd5e9..7d8bc474202 100644 --- a/exist-core/src/main/java/org/exist/validation/internal/DatabaseResources.java +++ b/exist-core/src/main/java/org/exist/validation/internal/DatabaseResources.java @@ -22,9 +22,6 @@ package org.exist.validation.internal; -import java.io.IOException; -import java.util.*; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.exist.EXistException; @@ -40,175 +37,176 @@ import org.exist.xquery.value.Sequence; import org.exist.xquery.value.SequenceIterator; +import java.io.IOException; +import java.util.*; + /** - * Helper class for accessing grammars. + * Helper class for accessing grammars. * * @author Dannes Wessels (dizzzz@exist-db.org) */ public class DatabaseResources { - + public final static String QUERY_LOCATION = "org/exist/validation/internal/query/"; - + public final static String FIND_XSD = QUERY_LOCATION + "find_schema_by_targetNamespace.xq"; - + public final static String FIND_CATALOGS_WITH_DTD = QUERY_LOCATION + "find_catalogs_with_dtd.xq"; - + public final static String PUBLICID = "publicId"; - + public final static String TARGETNAMESPACE = "targetNamespace"; - - public final static String CATALOG = "catalog"; - + + public final static String CATALOG = "catalog"; + public final static String COLLECTION = "collection"; - - /** Local reference to database */ - private BrokerPool brokerPool = null; - - /** Local logger */ + /** + * Local logger + */ private final static Logger logger = LogManager.getLogger(DatabaseResources.class); - - /** - * Convert sequence into list of strings. + * Local reference to database + */ + private BrokerPool brokerPool = null; + + + /** + * Creates a new instance of DatabaseResources. * - * @param sequence Result of query. - * @return List containing String objects. + * @param pool Instance shared broker pool. */ - public List getAllResults(Sequence sequence){ + public DatabaseResources(final BrokerPool pool) { + + logger.info("Initializing DatabaseResources"); + this.brokerPool = pool; + + } + + /** + * Convert sequence into list of strings. + * + * @param sequence Result of query. + * @return List containing String objects. + */ + public List getAllResults(final Sequence sequence) { List result = new ArrayList<>(); - + try { - final SequenceIterator i = sequence.iterate(); - while(i.hasNext()){ - final String path = i.nextItem().getStringValue(); + final SequenceIterator i = sequence.iterate(); + while (i.hasNext()) { + final String path = i.nextItem().getStringValue(); result.add(path); } - + } catch (final XPathException ex) { logger.error("xQuery issue.", ex); - result=null; + result = null; } - + return result; } - + /** - * Get first entry of sequence as String. + * Get first entry of sequence as String. * - * @param sequence Result of query. - * @return String containing representation of 1st entry of sequence. + * @param sequence Result of query. + * @return String containing representation of 1st entry of sequence. */ - public String getFirstResult(Sequence sequence){ + public String getFirstResult(final Sequence sequence) { String result = null; - + try { final SequenceIterator i = sequence.iterate(); - if(i.hasNext()){ - result= i.nextItem().getStringValue(); + if (i.hasNext()) { + result = i.nextItem().getStringValue(); logger.debug("Single query result: '{}'.", result); - + } else { logger.debug("No query result."); } - + } catch (final XPathException ex) { logger.error("xQuery issue ", ex); } - + return result; } - - - public Sequence executeQuery(String queryPath, Map params, Subject user){ - + + public Sequence executeQuery(final String queryPath, final Map params, final Subject user) { + final String namespace = params.get(TARGETNAMESPACE); final String publicId = params.get(PUBLICID); final String catalogPath = params.get(CATALOG); final String collection = params.get(COLLECTION); - - if(logger.isDebugEnabled()) { + + if (logger.isDebugEnabled()) { logger.debug("collection={} namespace={} publicId={} catalogPath={}", collection, namespace, publicId, catalogPath); } - Sequence result= null; + Sequence result = null; final XQueryContext context = new XQueryContext(brokerPool); - try(final DBBroker broker = brokerPool.get(Optional.ofNullable(user))) { + try (final DBBroker broker = brokerPool.get(Optional.ofNullable(user))) { final XQuery xquery = brokerPool.getXQueryService(); - - if(collection!=null){ + + if (collection != null) { context.declareVariable(COLLECTION, collection); } - - if(namespace!=null){ + + if (namespace != null) { context.declareVariable(TARGETNAMESPACE, namespace); } - - if(publicId!=null){ + + if (publicId != null) { context.declareVariable(PUBLICID, publicId); } - - if(catalogPath!=null){ + + if (catalogPath != null) { context.declareVariable(CATALOG, catalogPath); } - - CompiledXQuery compiled = xquery.compile(context, new ClassLoaderSource(queryPath) ); - + + final CompiledXQuery compiled = xquery.compile(context, new ClassLoaderSource(queryPath)); + result = xquery.execute(broker, compiled, null); - + } catch (final EXistException | XPathException | IOException | PermissionDeniedException ex) { logger.error("Problem executing xquery", ex); - result= null; + result = null; context.runCleanupTasks(); - + } return result; } - - - /** - * Creates a new instance of DatabaseResources. - * - * - * - * @param pool Instance shared broker pool. - */ - public DatabaseResources(BrokerPool pool) { - - logger.info("Initializing DatabaseResources"); - this.brokerPool = pool; - - } - - public String findXSD(String collection, String targetNamespace, Subject user){ - - if(logger.isDebugEnabled()) { + + public String findXSD(final String collection, final String targetNamespace, final Subject user) { + + if (logger.isDebugEnabled()) { logger.debug("Find schema with namespace '{}' in '{}'.", targetNamespace, collection); } - - final Map params = new HashMap<>(); + + final Map params = new HashMap<>(); params.put(COLLECTION, collection); params.put(TARGETNAMESPACE, targetNamespace); - - final Sequence result = executeQuery(FIND_XSD, params, user ); - + + final Sequence result = executeQuery(FIND_XSD, params, user); + return getFirstResult(result); } - - public String findCatalogWithDTD(String collection, String publicId, Subject user){ - - if(logger.isDebugEnabled()) { + + public String findCatalogWithDTD(final String collection, final String publicId, final Subject user) { + + if (logger.isDebugEnabled()) { logger.debug("Find DTD with public '{}' in '{}'.", publicId, collection); } - - final Map params = new HashMap<>(); + + final Map params = new HashMap<>(); params.put(COLLECTION, collection); params.put(PUBLICID, publicId); - - final Sequence result = executeQuery(FIND_CATALOGS_WITH_DTD, params, user ); - + + final Sequence result = executeQuery(FIND_CATALOGS_WITH_DTD, params, user); + return getFirstResult(result); } - + } diff --git a/exist-core/src/main/java/org/exist/validation/internal/node/NodeInputStream.java b/exist-core/src/main/java/org/exist/validation/internal/node/NodeInputStream.java index 1b86353c307..94169dfc4e8 100644 --- a/exist-core/src/main/java/org/exist/validation/internal/node/NodeInputStream.java +++ b/exist-core/src/main/java/org/exist/validation/internal/node/NodeInputStream.java @@ -22,16 +22,16 @@ package org.exist.validation.internal.node; -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.atomic.AtomicLong; - import com.evolvedbinary.j8fu.function.ConsumerE; import org.exist.Database; import org.exist.storage.io.BlockingInputStream; import org.exist.storage.serializers.Serializer; import org.exist.xquery.value.NodeValue; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.atomic.AtomicLong; + import static org.exist.util.ThreadUtils.newInstanceThread; /** @@ -40,16 +40,15 @@ * @author Dannes Wessels (dizzzz@exist-db.org) */ public class NodeInputStream extends InputStream { - private final BlockingInputStream bis; - private static final AtomicLong nodeSerializerThreadId = new AtomicLong(); + private final BlockingInputStream bis; /** * Creates a new instance of NodeInputStream. * - * @param database The database. + * @param database The database. * @param withSerializerFn The serializer closure. - * @param node The node that is serialized. + * @param node The node that is serialized. */ public NodeInputStream(final Database database, final ConsumerE, IOException> withSerializerFn, final NodeValue node) { this.bis = new BlockingInputStream(); @@ -58,17 +57,17 @@ public NodeInputStream(final Database database, final ConsumerE, IOException> withSerializer; @@ -50,21 +50,21 @@ public class NodeSerializerRunnable implements Runnable { * Creates a new instance of NodeSerializerRunnable. * * @param withSerializer The serializer closure. - * @param node The node to be serialized. - * @param bos Blocking outputstream. + * @param node The node to be serialized. + * @param bos Blocking outputstream. */ - public NodeSerializerRunnable(final ConsumerE, IOException> withSerializer, final NodeValue node, final BlockingOutputStream bos) { + public NodeSerializerRunnable(final ConsumerE, IOException> withSerializer, final NodeValue node, final BlockingOutputStream bos) { this.withSerializer = withSerializer; this.node = node; this.bos = bos; } - + /** * Write resource to the output stream. */ @Override public void run() { - IOException exception=null; + IOException exception = null; try { //parse serialization options final Properties outputProperties = new Properties(); @@ -72,13 +72,13 @@ public void run() { outputProperties.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); withSerializer.accept(serializer -> - NodeSerializer.serialize(serializer, node, outputProperties, bos) + NodeSerializer.serialize(serializer, node, outputProperties, bos) ); } catch (final IOException ex) { logger.error(ex); exception = ex; - + } finally { try { // NEEDED! bos.close(exception); diff --git a/exist-core/src/main/java/org/exist/validation/resolver/AnyUriResolver.java b/exist-core/src/main/java/org/exist/validation/resolver/AnyUriResolver.java index c639a927695..7b54d3ee3d2 100644 --- a/exist-core/src/main/java/org/exist/validation/resolver/AnyUriResolver.java +++ b/exist-core/src/main/java/org/exist/validation/resolver/AnyUriResolver.java @@ -22,9 +22,6 @@ package org.exist.validation.resolver; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.xerces.xni.XMLResourceIdentifier; @@ -35,11 +32,15 @@ import org.exist.protocolhandler.xmldb.XmldbURL; import org.exist.protocolhandler.xmlrpc.XmlrpcInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + import static java.nio.charset.StandardCharsets.UTF_8; /** - * Resolve a resource specified by xs:anyURI. First time the - * resource is resolved by the URL as specified in the constructor, + * Resolve a resource specified by xs:anyURI. First time the + * resource is resolved by the URL as specified in the constructor, * the second the URL of the ExpandedSystemId is used. * * @author Dannes Wessels (dizzzz@exist-db.org) @@ -47,36 +48,34 @@ public class AnyUriResolver implements XMLEntityResolver { private static final Logger LOG = LogManager.getLogger(AnyUriResolver.class); private static final ThreadGroup threadGroup = new ThreadGroup("exist.xml-entity-resolver"); - - private String docPath; private final String parentURI; - - private boolean firstTime=true; + private String docPath; + private boolean firstTime = true; /** * Creates a new instance of AnyUriResolver. * * @param path Original path of resource. */ - public AnyUriResolver(String path) { - docPath=path; - if(docPath.startsWith("/")){ - docPath="xmldb:exist://"+docPath; + public AnyUriResolver(final String path) { + docPath = path; + if (docPath.startsWith("/")) { + docPath = "xmldb:exist://" + docPath; } LOG.debug("Specified path={}", path); - - if(path.lastIndexOf('/')!=-1){ - parentURI=path.substring(0, path.lastIndexOf('/')); + + if (path.lastIndexOf('/') != -1) { + parentURI = path.substring(0, path.lastIndexOf('/')); LOG.debug("parentURI={}", parentURI); } else { - parentURI=""; + parentURI = ""; } } - + @Override - public XMLInputSource resolveEntity(XMLResourceIdentifier xri) throws XNIException, IOException { - + public XMLInputSource resolveEntity(final XMLResourceIdentifier xri) throws XNIException, IOException { + if (xri.getExpandedSystemId() == null && xri.getLiteralSystemId() == null && xri.getNamespace() == null && xri.getPublicId() == null) { @@ -121,7 +120,8 @@ public XMLInputSource resolveEntity(XMLResourceIdentifier xri) throws XNIExcepti } } else { - is = new URL(resourcePath).openStream(); + + is = URI.create(resourcePath).toURL().openStream(); } final XMLInputSource xis = new XMLInputSource(xri.getPublicId(), resourcePath, @@ -134,13 +134,13 @@ public XMLInputSource resolveEntity(XMLResourceIdentifier xri) throws XNIExcepti return xis; } - - private String getXriDetails(XMLResourceIdentifier xrid){ + + private String getXriDetails(final XMLResourceIdentifier xrid) { return "PublicId='" + xrid.getPublicId() + "' " + "BaseSystemId='" + xrid.getBaseSystemId() + "' " + "ExpandedSystemId='" + xrid.getExpandedSystemId() + "' " + "LiteralSystemId='" + xrid.getLiteralSystemId() + "' " + "Namespace='" + xrid.getNamespace() + "' "; } - private String getXisDetails(XMLInputSource xis){ + private String getXisDetails(final XMLInputSource xis) { return "PublicId='" + xis.getPublicId() + "' " + "SystemId='" + xis.getSystemId() + "' " + "BaseSystemId='" + xis.getBaseSystemId() + "' " + "Encoding='" + xis.getEncoding() + "' "; } - + } diff --git a/exist-core/src/main/java/org/exist/validation/resolver/SearchResourceResolver.java b/exist-core/src/main/java/org/exist/validation/resolver/SearchResourceResolver.java index b72f34ed7cc..61f80070a36 100644 --- a/exist-core/src/main/java/org/exist/validation/resolver/SearchResourceResolver.java +++ b/exist-core/src/main/java/org/exist/validation/resolver/SearchResourceResolver.java @@ -22,16 +22,6 @@ package org.exist.validation.resolver; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.io.StringWriter; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.Arrays; -import java.util.Optional; -import java.util.Properties; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.xerces.xni.XMLResourceIdentifier; @@ -59,6 +49,15 @@ import org.xmlresolver.Resolver; import javax.xml.transform.OutputKeys; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.io.StringWriter; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Optional; +import java.util.Properties; import static com.evolvedbinary.j8fu.tuple.Tuple.Tuple; import static java.nio.charset.StandardCharsets.UTF_8; @@ -82,7 +81,7 @@ public SearchResourceResolver(final BrokerPool brokerPool, final Subject subject this.collectionPath = collectionPath; if (LOG.isDebugEnabled()) { - LOG.debug("Specified collectionPath=" + collectionPath); + LOG.debug("Specified collectionPath={}", collectionPath); } } @@ -95,7 +94,7 @@ public XMLInputSource resolveEntity(final XMLResourceIdentifier xri) throws XNIE } if (LOG.isDebugEnabled()) { - LOG.debug("Resolving XMLResourceIdentifier: " + getXriDetails(xri)); + LOG.debug("Resolving XMLResourceIdentifier: {}", getXriDetails(xri)); } @@ -105,7 +104,7 @@ public XMLInputSource resolveEntity(final XMLResourceIdentifier xri) throws XNIE if (xri.getNamespace() != null) { // XML Schema search if (LOG.isDebugEnabled()) { - LOG.debug("Searching namespace '" + xri.getNamespace() + "' in database from " + collectionPath + "..."); + LOG.debug("Searching namespace '{}' in database from {}...", xri.getNamespace(), collectionPath); } resourcePath = databaseResources.findXSD(collectionPath, xri.getNamespace(), subject); @@ -113,12 +112,12 @@ public XMLInputSource resolveEntity(final XMLResourceIdentifier xri) throws XNIE } else if (xri.getPublicId() != null) { // Catalog search if (LOG.isDebugEnabled()) { - LOG.debug("Searching publicId '" + xri.getPublicId() + "' in catalogs in database from " + collectionPath + "..."); + LOG.debug("Searching publicId '{}' in catalogs in database from {}...", xri.getPublicId(), collectionPath); } String catalogPath = databaseResources.findCatalogWithDTD(collectionPath, xri.getPublicId(), subject); if (LOG.isDebugEnabled()) { - LOG.debug("Found publicId in catalog '" + catalogPath + "'"); + LOG.debug("Found publicId in catalog '{}'", catalogPath); } if (catalogPath != null) { @@ -143,7 +142,7 @@ public XMLInputSource resolveEntity(final XMLResourceIdentifier xri) throws XNIE maybeInputSource.get().setSystemId(catalogPath); } - final Resolver resolver = ResolverFactory.newResolver(Arrays.asList(Tuple(catalogPath, maybeInputSource))); + final Resolver resolver = ResolverFactory.newResolver(List.of(Tuple(catalogPath, maybeInputSource))); final InputSource source = resolver.resolveEntity(xri.getPublicId(), ""); if (source != null) { resourcePath = source.getSystemId(); @@ -169,15 +168,15 @@ public XMLInputSource resolveEntity(final XMLResourceIdentifier xri) throws XNIE resourcePath = ResolverFactory.fixupExistCatalogUri(resourcePath); if (LOG.isDebugEnabled()) { - LOG.debug("resourcePath='" + resourcePath + "'"); + LOG.debug("resourcePath='{}'", resourcePath); } - - final InputStream is = new URL(resourcePath).openStream(); + + final InputStream is = URI.create(resourcePath).toURL().openStream(); final XMLInputSource xis = new XMLInputSource(xri.getPublicId(), xri.getExpandedSystemId(), xri.getBaseSystemId(), is, UTF_8.name()); if (LOG.isDebugEnabled()) { - LOG.debug("XMLInputSource: " + getXisDetails(xis)); + LOG.debug("XMLInputSource: {}", getXisDetails(xis)); } return xis; diff --git a/exist-core/src/main/java/org/exist/validation/resolver/unstable/ExistResolver.java b/exist-core/src/main/java/org/exist/validation/resolver/unstable/ExistResolver.java index 8547099114f..7ed92cfc3ff 100644 --- a/exist-core/src/main/java/org/exist/validation/resolver/unstable/ExistResolver.java +++ b/exist-core/src/main/java/org/exist/validation/resolver/unstable/ExistResolver.java @@ -21,14 +21,6 @@ */ package org.exist.validation.resolver.unstable; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import javax.xml.transform.Source; -import javax.xml.transform.TransformerException; -import javax.xml.transform.URIResolver; -import javax.xml.transform.stream.StreamSource; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.exist.protocolhandler.embedded.EmbeddedInputStream; @@ -38,6 +30,15 @@ import org.xml.sax.SAXException; import org.xml.sax.ext.EntityResolver2; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.URIResolver; +import javax.xml.transform.stream.StreamSource; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + /** * * @author dizzzz@exist-db.org @@ -45,20 +46,18 @@ public class ExistResolver implements EntityResolver2, URIResolver { private final static Logger LOG = LogManager.getLogger(ExistResolver.class); - - private BrokerPool brokerPool = null; - private final static String LOCALURI = "xmldb:exist:///"; private final static String SHORTLOCALURI = "xmldb:///"; + private BrokerPool brokerPool = null; - public ExistResolver(BrokerPool brokerPool) { + public ExistResolver(final BrokerPool brokerPool) { this.brokerPool = brokerPool; } /* ========================================== */ /* SAX1: interface org.xml.sax.EntityResolver */ /* ========================================== */ - public InputSource resolveEntity(String publicId, String systemId) + public InputSource resolveEntity(final String publicId, final String systemId) throws SAXException, IOException { LOG.debug("publicId={} systemId={}", publicId, systemId); @@ -69,7 +68,7 @@ public InputSource resolveEntity(String publicId, String systemId) /* =============================================== */ /* SAX2: interface org.xml.sax.ext.EntityResolver2 */ /* =============================================== */ - public InputSource getExternalSubset(String name, String baseURI) + public InputSource getExternalSubset(final String name, final String baseURI) throws SAXException, IOException { LOG.debug("name={} baseURI={}", name, baseURI); @@ -77,8 +76,8 @@ public InputSource getExternalSubset(String name, String baseURI) return resolveInputSource(brokerPool, baseURI); } - public InputSource resolveEntity(String name, String publicId, - String baseURI, String systemId) throws SAXException, IOException { + public InputSource resolveEntity(final String name, final String publicId, + final String baseURI, final String systemId) throws SAXException, IOException { LOG.debug("name={} publicId={} baseURI={} systemId={}", name, publicId, baseURI, systemId); @@ -92,15 +91,15 @@ public Source resolve(String href, String base) throws TransformerException { LOG.debug("href={} base={}", href, base); - if(base!=null){ - String sep = "/"; - if (base.startsWith("file:")) { - sep = File.separator; - } + if (base != null) { + String sep = "/"; + if (base.startsWith("file:")) { + sep = File.separator; + } final int pos = base.lastIndexOf(sep); - if(pos!=-1){ - base=base.substring(0, pos); - href=base + sep + href; + if (pos != -1) { + base = base.substring(0, pos); + href = base + sep + href; } } @@ -110,9 +109,9 @@ public Source resolve(String href, String base) throws TransformerException { /* ============== */ /* Helper methods */ /* ============== */ - private InputSource resolveInputSource(BrokerPool bPool, String path) throws IOException { + private InputSource resolveInputSource(final BrokerPool bPool, final String path) throws IOException { - LOG.debug("Resolving {}", path); + LOG.debug("Resolving inputSource {}", path); final InputSource inputsource = new InputSource(); @@ -125,7 +124,7 @@ private InputSource resolveInputSource(BrokerPool bPool, String path) throws IOE inputsource.setSystemId(path); } else { - final InputStream is = new URL(path).openStream(); + final InputStream is = URI.create(path).toURL().openStream(); inputsource.setByteStream(is); inputsource.setSystemId(path); } @@ -133,10 +132,10 @@ private InputSource resolveInputSource(BrokerPool bPool, String path) throws IOE return inputsource; } - private StreamSource resolveStreamSource(BrokerPool bPool, String path) throws TransformerException { + private StreamSource resolveStreamSource(final BrokerPool bPool, final String path) throws TransformerException { + + LOG.debug("Resolving streamSource {}", path); - LOG.debug("Resolving {}", path); - final StreamSource streamsource = new StreamSource(); try { @@ -148,16 +147,16 @@ private StreamSource resolveStreamSource(BrokerPool bPool, String path) throws T streamsource.setSystemId(path); } else { - final InputStream is = new URL(path).openStream(); + final InputStream is = URI.create(path).toURL().openStream(); streamsource.setInputStream(is); streamsource.setSystemId(path); } } - + } catch (final IOException ex) { throw new TransformerException(ex); } - + return streamsource; } } diff --git a/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSInput.java b/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSInput.java index a8e8575b5ee..411b82dd382 100644 --- a/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSInput.java +++ b/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSInput.java @@ -21,108 +21,91 @@ */ package org.exist.validation.resolver.unstable; -import java.io.InputStream; -import java.io.Reader; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.w3c.dom.ls.LSInput; +import java.io.InputStream; +import java.io.Reader; + /** * eXistLSInput provides a way for applications to redirect * references to external resource. - * + * * @author Dizzzz (dizzzz@exist-db.org) */ public class eXistLSInput implements LSInput { - @SuppressWarnings("unused") - private final static Logger LOG = LogManager.getLogger(eXistLSInput.class); - private Reader characterStream; + private InputStream byteStream; + private String stringData; + private String systemId; + private String publicId; + private String baseURI; + private String encoding; + private boolean certifiedText = false; public Reader getCharacterStream() { return characterStream; } - public void setCharacterStream(Reader characterStream) { - this.characterStream=characterStream; + public void setCharacterStream(final Reader characterStream) { + this.characterStream = characterStream; } - private InputStream byteStream; - public InputStream getByteStream() { return byteStream; } - public void setByteStream(InputStream byteStream) { - this.byteStream=byteStream; + public void setByteStream(final InputStream byteStream) { + this.byteStream = byteStream; } - - private String stringData; - public String getStringData() { return stringData; } - public void setStringData(String stringData) { - this.stringData=stringData; + public void setStringData(final String stringData) { + this.stringData = stringData; } - - private String systemId; - public String getSystemId() { return systemId; } - public void setSystemId(String systemId) { - this.systemId=systemId; + public void setSystemId(final String systemId) { + this.systemId = systemId; } - - private String publicId; - public String getPublicId() { return publicId; } - public void setPublicId(String publicId) { - this.publicId=publicId; + public void setPublicId(final String publicId) { + this.publicId = publicId; } - - private String baseURI; - public String getBaseURI() { return baseURI; } - public void setBaseURI(String baseURI) { - this.baseURI=baseURI; + public void setBaseURI(final String baseURI) { + this.baseURI = baseURI; } - - private String encoding; - public String getEncoding() { return encoding; } - public void setEncoding(String encoding) { - this.encoding=encoding; + public void setEncoding(final String encoding) { + this.encoding = encoding; } - - private boolean certifiedText=false; - public boolean getCertifiedText() { return certifiedText; } - public void setCertifiedText(boolean certifiedText) { - this.certifiedText=certifiedText; + public void setCertifiedText(final boolean certifiedText) { + this.certifiedText = certifiedText; } - - } diff --git a/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSResourceResolver.java b/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSResourceResolver.java index 2f09580f45d..07250e3a528 100644 --- a/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSResourceResolver.java +++ b/exist-core/src/main/java/org/exist/validation/resolver/unstable/eXistLSResourceResolver.java @@ -21,10 +21,6 @@ */ package org.exist.validation.resolver.unstable; -import java.io.IOException; -import java.io.InputStream; -import java.net.MalformedURLException; -import java.net.URL; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.exist.protocolhandler.embedded.EmbeddedInputStream; @@ -33,20 +29,24 @@ import org.w3c.dom.ls.LSInput; import org.w3c.dom.ls.LSResourceResolver; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; + /** * eXistLSResourceResolver provides a way for applications to redirect * references to external resource. - * + *

* To be used by @see javax.xml.validation.Validator - * + * * @author Dizzzz (dizzzz@exist-db.org) */ public class eXistLSResourceResolver implements LSResourceResolver { private static final Logger LOG = LogManager.getLogger(eXistLSResourceResolver.class); private static final ThreadGroup threadGroup = new ThreadGroup("exist.ls-resolver"); - public LSInput resolveResource(String type, String namespaceURI, - String publicId, String systemId, String baseURI) { + public LSInput resolveResource(final String type, final String namespaceURI, + final String publicId, final String systemId, final String baseURI) { LOG.debug("type={} namespaceURI={} publicId={} systemId={} baseURI={}", type, namespaceURI, publicId, systemId, baseURI); @@ -58,16 +58,16 @@ public LSInput resolveResource(String type, String namespaceURI, } catch (final Exception ex) { LOG.error(ex.getMessage()); - lsInput=null; - } + lsInput = null; + } return lsInput; } - private InputStream getInputStream(String resourcePath) throws MalformedURLException, IOException{ + private InputStream getInputStream(String resourcePath) throws IOException { - if(resourcePath.startsWith("/db")){ - resourcePath="xmldb:exist://"+resourcePath; + if (resourcePath.startsWith("/db")) { + resourcePath = "xmldb:exist://" + resourcePath; } InputStream is = null; @@ -81,7 +81,7 @@ private InputStream getInputStream(String resourcePath) throws MalformedURLExcep } } else { - is = new URL(resourcePath).openStream(); + is = URI.create(resourcePath).toURL().openStream(); } return is; } diff --git a/exist-core/src/main/java/org/exist/xquery/functions/validation/GrammarTooling.java b/exist-core/src/main/java/org/exist/xquery/functions/validation/GrammarTooling.java index 19a91182fd2..dd47bccf88b 100644 --- a/exist-core/src/main/java/org/exist/xquery/functions/validation/GrammarTooling.java +++ b/exist-core/src/main/java/org/exist/xquery/functions/validation/GrammarTooling.java @@ -37,7 +37,6 @@ import org.exist.dom.memtree.NodeImpl; import org.exist.storage.BrokerPool; import org.exist.util.Configuration; -import org.exist.util.XMLReaderObjectFactory; import org.exist.validation.GrammarPool; import org.exist.xquery.BasicFunction; import org.exist.xquery.Cardinality; @@ -139,7 +138,7 @@ public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException { final GrammarPool grammarpool - = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL); + = (GrammarPool) config.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT); if (isCalledAs("clear-grammar-cache")){ diff --git a/exist-core/src/main/java/org/exist/xquery/functions/validation/Jaxp.java b/exist-core/src/main/java/org/exist/xquery/functions/validation/Jaxp.java index 6b37b2730ea..490933d99d7 100644 --- a/exist-core/src/main/java/org/exist/xquery/functions/validation/Jaxp.java +++ b/exist-core/src/main/java/org/exist/xquery/functions/validation/Jaxp.java @@ -283,7 +283,7 @@ public Sequence eval(final Sequence[] args, final Sequence contextSequence) thro if (useCache) { LOG.debug("Grammar caching enabled."); final Configuration config = brokerPool.getConfiguration(); - final GrammarPool grammarPool = (GrammarPool) config.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL); + final GrammarPool grammarPool = (GrammarPool) config.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT); xmlReader.setProperty(XMLReaderObjectFactory.APACHE_PROPERTIES_INTERNAL_GRAMMARPOOL, grammarPool); } diff --git a/exist-core/src/test/java/org/exist/util/XMLReaderPoolTest.java b/exist-core/src/test/java/org/exist/util/XMLReaderPoolTest.java index 61f679bcec2..6d089c6e316 100644 --- a/exist-core/src/test/java/org/exist/util/XMLReaderPoolTest.java +++ b/exist-core/src/test/java/org/exist/util/XMLReaderPoolTest.java @@ -48,7 +48,7 @@ public class XMLReaderPoolTest { @ValueSource(strings = {"yes", "YES", "true", "TRUE", "auto", "AUTO"}) public void xmlReaderWithEnabledValidation(final String validationMode) throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn(validationMode); @@ -84,7 +84,7 @@ public void xmlReaderWithEnabledValidation(final String validationMode) throws S @ValueSource(strings = {"no", "NO", "false", "FALSE"}) public void xmlReaderWithDisabledValidation(final String validationMode) throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn(validationMode); @@ -115,7 +115,7 @@ public void xmlReaderWithDisabledValidation(final String validationMode) throws @Test public void xmlReaderWithUnknownValidation() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("unknown"); @@ -148,7 +148,7 @@ public void xmlReaderWithGrammarPool() throws SAXNotSupportedException, SAXNotRe final GrammarPool mockGrammarPool = createMock(GrammarPool.class); final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(mockGrammarPool); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(mockGrammarPool); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -175,7 +175,7 @@ public void xmlReaderWithGrammarPool() throws SAXNotSupportedException, SAXNotRe @Test public void xmlReaderWithoutGrammarPool() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -204,7 +204,7 @@ public void xmlReaderWithResolver() throws SAXNotSupportedException, SAXNotRecog final Resolver mockResolver = createMock(Resolver.class); final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(mockResolver); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -233,7 +233,7 @@ public void xmlReaderWithResolver() throws SAXNotSupportedException, SAXNotRecog @Test public void xmlReaderWithoutResolver() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -260,7 +260,7 @@ public void xmlReaderWithoutResolver() throws SAXNotSupportedException, SAXNotRe @Test public void xmlReaderWithConfiguredFeatures() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -294,7 +294,7 @@ public void xmlReaderWithConfiguredFeatures() throws SAXNotSupportedException, S @Test public void xmlReaderWithoutConfiguredFeatures() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -323,7 +323,7 @@ public void xmlReaderWithoutConfiguredFeatures() throws SAXNotSupportedException @Test public void xmlReaderHasNoContentHandler() { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -350,7 +350,7 @@ public void xmlReaderHasNoContentHandler() { @Test public void xmlReaderHasNoErrorHandler() { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -377,7 +377,7 @@ public void xmlReaderHasNoErrorHandler() { @Test public void xmlReaderHasNoLexicalHandler() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -405,7 +405,7 @@ public void xmlReaderHasNoLexicalHandler() throws SAXNotSupportedException, SAXN @ValueSource(strings = {"yes", "YES", "true", "TRUE", "auto", "AUTO" }) public void reusedXmlReaderStillHasEnabledValidation(final String validationMode) throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn(validationMode); @@ -460,7 +460,7 @@ public void reusedXmlReaderStillHasEnabledValidation(final String validationMode @ValueSource(strings = {"no", "NO", "false", "FALSE"}) public void reusedXmlReaderStillHasDisabledValidation(final String validationMode) throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn(validationMode); @@ -510,7 +510,7 @@ public void reusedXmlReaderStillHasDisabledValidation(final String validationMod @Test public void reusedXmlReaderStillHasUnknownValidation() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("unknown"); @@ -558,7 +558,7 @@ public void reusedXmlReaderStillHasGrammarPool() throws SAXNotSupportedException final GrammarPool mockGrammarPool = createMock(GrammarPool.class); final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(mockGrammarPool); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(mockGrammarPool); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -596,7 +596,7 @@ public void reusedXmlReaderStillHasGrammarPool() throws SAXNotSupportedException @Test public void reusedXmlReaderStillHasNoGrammarPool() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -637,7 +637,7 @@ public void reusedXmlReaderStillHasResolver() throws SAXNotSupportedException, S final Resolver mockResolver = createMock(Resolver.class); final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(mockResolver); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -677,7 +677,7 @@ public void reusedXmlReaderStillHasResolver() throws SAXNotSupportedException, S @Test public void reusedXmlReaderStillHasNoResolver() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -716,7 +716,7 @@ public void reusedXmlReaderStillHasNoResolver() throws SAXNotSupportedException, @Test public void reusedXmlReaderStillHasConfiguredFeatures() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -763,7 +763,7 @@ public void reusedXmlReaderStillHasConfiguredFeatures() throws SAXNotSupportedEx @Test public void reusedXmlReaderStillHasNoContentHandler() { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -802,7 +802,7 @@ public void reusedXmlReaderStillHasNoContentHandler() { @Test public void reusedXmlReaderStillHasNoErrorHandler() { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -841,7 +841,7 @@ public void reusedXmlReaderStillHasNoErrorHandler() { @Test public void reusedXmlReaderStillHasNoLexicalHandler() throws SAXNotSupportedException, SAXNotRecognizedException { final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); @@ -883,7 +883,7 @@ public void exceedMaxIdle() { final int initialCapacity = 0; final Configuration mockConfiguration = createMock(Configuration.class); - expect(mockConfiguration.getProperty(XMLReaderObjectFactory.GRAMMAR_POOL)).andReturn(null); + expect(mockConfiguration.getProperty(GrammarPool.GRAMMAR_POOL_ELEMENT)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.CATALOG_RESOLVER)).andReturn(null); expect(mockConfiguration.getProperty(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE)).andReturn("auto"); diff --git a/exist-core/src/test/java/org/exist/validation/ApacheXmlComponentsTest.java b/exist-core/src/test/java/org/exist/validation/ApacheXmlComponentsTest.java index 8f87922e3cf..a35fad18db7 100644 --- a/exist-core/src/test/java/org/exist/validation/ApacheXmlComponentsTest.java +++ b/exist-core/src/test/java/org/exist/validation/ApacheXmlComponentsTest.java @@ -22,32 +22,33 @@ package org.exist.validation; -import org.junit.*; -import static org.junit.Assert.*; +import org.junit.Test; + +import static org.junit.Assert.assertTrue; /** - * Class for testing XML Parser and XML Transformer configuration. + * Class for testing XML Parser and XML Transformer configuration. * * @author Dannes Wessels (dizzzz@exist-db.org) */ -public class ApacheXmlComponentsTest { - - +public class ApacheXmlComponentsTest { + + @Test public void parserVersion() { - StringBuilder xmlLibMessage = new StringBuilder(); - - boolean validParser = XmlLibraryChecker.hasValidParser(xmlLibMessage); - + final StringBuilder xmlLibMessage = new StringBuilder(); + + final boolean validParser = XmlLibraryChecker.hasValidParser(xmlLibMessage); + assertTrue(xmlLibMessage.toString(), validParser); } @Test public void transformerVersion() { - StringBuilder xmlLibMessage = new StringBuilder(); - - boolean validTransformer = XmlLibraryChecker.hasValidTransformer(xmlLibMessage); - + final StringBuilder xmlLibMessage = new StringBuilder(); + + final boolean validTransformer = XmlLibraryChecker.hasValidTransformer(xmlLibMessage); + assertTrue(xmlLibMessage.toString(), validTransformer); } } diff --git a/exist-core/src/test/java/org/exist/validation/CollectionConfigurationTest.java b/exist-core/src/test/java/org/exist/validation/CollectionConfigurationTest.java index 6747662d239..a02cad3ec0f 100644 --- a/exist-core/src/test/java/org/exist/validation/CollectionConfigurationTest.java +++ b/exist-core/src/test/java/org/exist/validation/CollectionConfigurationTest.java @@ -23,19 +23,19 @@ import org.exist.test.ExistXmldbEmbeddedServer; import org.junit.ClassRule; -import org.xmldb.api.base.Collection; -import org.xmldb.api.base.XMLDBException; import org.junit.Test; - +import org.xmldb.api.base.Collection; import org.xmldb.api.base.ResourceSet; +import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.CollectionManagementService; import static org.exist.collections.CollectionConfiguration.DEFAULT_COLLECTION_CONFIG_FILE; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; /** - * Some tests regarding invalid collection.xconf documents. - * + * Some tests regarding invalid collection.xconf documents. + * * @author wessels */ public class CollectionConfigurationTest { @@ -45,7 +45,7 @@ public class CollectionConfigurationTest { private static final String invalidConfig = ""; - private void createCollection(String collection) throws XMLDBException { + private void createCollection(final String collection) throws XMLDBException { final CollectionManagementService cmservice = existEmbeddedServer.getRoot().getService(CollectionManagementService.class); Collection testCollection = cmservice.createCollection(collection); assertNotNull(testCollection); @@ -54,9 +54,9 @@ private void createCollection(String collection) throws XMLDBException { assertNotNull(testCollection); } - private void storeCollectionXconf(String collection, String document) throws XMLDBException { + private void storeCollectionXconf(final String collection, final String document) throws XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery("xmldb:store(\"" + collection + "\", \"" + DEFAULT_COLLECTION_CONFIG_FILE + "\", " + document + ")"); - String r = (String) result.getResource(0).getContent(); + final String r = (String) result.getResource(0).getContent(); assertEquals("Store xconf", collection + "/" + DEFAULT_COLLECTION_CONFIG_FILE, r); } diff --git a/exist-core/src/test/java/org/exist/validation/CollectionConfigurationValidationModeTest.java b/exist-core/src/test/java/org/exist/validation/CollectionConfigurationValidationModeTest.java index d5cb1252da1..87d00711811 100644 --- a/exist-core/src/test/java/org/exist/validation/CollectionConfigurationValidationModeTest.java +++ b/exist-core/src/test/java/org/exist/validation/CollectionConfigurationValidationModeTest.java @@ -37,7 +37,8 @@ import static org.junit.Assert.*; /** - * Switch validation mode yes/no/auto per collection and validate. + * Switch validation mode yes/no/auto per collection and validate. + * * @author wessels */ public class CollectionConfigurationValidationModeTest { @@ -204,8 +205,8 @@ public void insertModeTrue() throws XMLDBException { try { storeDocument("/db/true", "invalid.xml", INVALID_XSD); fail("should have failed"); - } catch (XMLDBException ex) { - String msg = ex.getMessage(); + } catch (final XMLDBException ex) { + final String msg = ex.getMessage(); assertTrue(msg.contains("cvc-complex-type.2.4.a: Invalid content was found")); } @@ -213,8 +214,8 @@ public void insertModeTrue() throws XMLDBException { try { storeDocument("/db/true", "anonymous.xml", ANONYMOUS_XSD); fail("should have failed"); - } catch (XMLDBException ex) { - String msg = ex.getMessage(); + } catch (final XMLDBException ex) { + final String msg = ex.getMessage(); assertTrue(msg.contains("cvc-elt.1.a: Cannot find the declaration of element 'schema'.")); } @@ -222,8 +223,8 @@ public void insertModeTrue() throws XMLDBException { try { storeDocument("/db/true", "different.xml", DIFFERENT_XSD); fail("should have failed"); - } catch (XMLDBException ex) { - String msg = ex.getMessage(); + } catch (final XMLDBException ex) { + final String msg = ex.getMessage(); assertTrue(msg.contains("cvc-elt.1.a: Cannot find the declaration of element 'xsd:schema'")); } } @@ -240,8 +241,8 @@ public void insertModeAuto() throws XMLDBException { try { storeDocument("/db/auto", "invalid.xml", INVALID_XSD); fail("should have failed"); - } catch (XMLDBException ex) { - String msg = ex.getMessage(); + } catch (final XMLDBException ex) { + final String msg = ex.getMessage(); assertTrue(msg.contains("cvc-complex-type.2.4.a: Invalid content was found")); } @@ -251,8 +252,8 @@ public void insertModeAuto() throws XMLDBException { // non resolvable namespace provided, should fail try { storeDocument("/db/auto", "different.xml", DIFFERENT_XSD); - } catch (XMLDBException ex) { - String msg = ex.getMessage(); + } catch (final XMLDBException ex) { + final String msg = ex.getMessage(); assertTrue(msg.contains("schema_reference.4: Failed to read schema document")); } } diff --git a/exist-core/src/test/java/org/exist/validation/DatabaseCollectionTest.java b/exist-core/src/test/java/org/exist/validation/DatabaseCollectionTest.java index c860f637d6f..84caaedaa64 100644 --- a/exist-core/src/test/java/org/exist/validation/DatabaseCollectionTest.java +++ b/exist-core/src/test/java/org/exist/validation/DatabaseCollectionTest.java @@ -25,10 +25,8 @@ import org.exist.security.Account; import org.exist.security.Permission; import org.exist.test.ExistXmldbEmbeddedServer; - import org.exist.xmldb.UserManagementService; import org.exist.xmldb.XmldbURI; - import org.junit.After; import org.junit.Before; import org.junit.ClassRule; @@ -41,7 +39,7 @@ import static org.junit.Assert.assertNotNull; /** - * Created collections needed for validation tests. + * Created collections needed for validation tests. * * @author Dannes Wessels (dizzzz@exist-db.org) */ @@ -71,7 +69,7 @@ public void tearDown() throws XMLDBException { final CollectionManagementService cms = existServer.getRoot().getService(CollectionManagementService.class); cms.removeCollection(TEST_COLLECTION); } - + @Test public void createCollections() throws XMLDBException { final Collection testCollection = DatabaseManager.getCollection(ROOT_URI + "/" + TEST_COLLECTION); diff --git a/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_NoValidation_Test.java b/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_NoValidation_Test.java index fa4efce743f..1889e6123f0 100644 --- a/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_NoValidation_Test.java +++ b/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_NoValidation_Test.java @@ -21,10 +21,6 @@ */ package org.exist.validation; -import java.io.IOException; -import java.io.InputStream; -import java.util.Optional; - import org.exist.collections.Collection; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; @@ -39,21 +35,84 @@ import org.junit.ClassRule; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; + import static org.exist.TestUtils.*; -import static org.exist.util.PropertiesBuilder.propertiesBuilder; import static org.exist.samples.Samples.SAMPLES; +import static org.exist.util.PropertiesBuilder.propertiesBuilder; /** - * Insert documents for validation tests. + * Insert documents for validation tests. * * @author Dannes Wessels (dizzzz@exist-db.org) */ public class DatabaseInsertResources_NoValidation_Test { + @ClassRule + public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer( + propertiesBuilder() + .set(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, "auto") + .build(), + true, + true); private final static String TEST_COLLECTION = "testNoValidationInsert"; - private final static String VALIDATION_HOME_COLLECTION_URI = "/db/" + TEST_COLLECTION + "/" + TestTools.VALIDATION_HOME_COLLECTION; - + + @BeforeClass + public static void startup() throws Exception { + //create the collections we need for these tests + createTestCollections(); + } + + @AfterClass + public static void shutdown() throws Exception { + removeTestCollections(); + } + + private static void createTestCollections() throws Exception { + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); + final TransactionManager transact = pool.getTransactionManager(); + + try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); + final Txn txn = transact.beginTransaction()) { + + /** create necessary collections if they dont exist */ + final Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); + testCollection.getPermissions().setOwner(GUEST_DB_USER); + broker.saveCollection(txn, testCollection); + + Collection col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_DTD_COLLECTION)); + col.getPermissions().setOwner(GUEST_DB_USER); + broker.saveCollection(txn, col); + + col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_XSD_COLLECTION)); + col.getPermissions().setOwner(GUEST_DB_USER); + broker.saveCollection(txn, col); + + col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION)); + col.getPermissions().setOwner(GUEST_DB_USER); + broker.saveCollection(txn, col); + + transact.commit(txn); + } + } + + private static void removeTestCollections() throws Exception { + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); + final TransactionManager transact = pool.getTransactionManager(); + + try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); + final Txn txn = transact.beginTransaction()) { + + /** create necessary collections if they dont exist */ + final Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); + broker.removeCollection(txn, testCollection); + + transact.commit(txn); + } + } /** * Insert all documents into database, switch of validation. @@ -125,66 +184,4 @@ public void insertValidationResource_dtd_badDocType() throws IOException { "xmldb:exist://" + VALIDATION_HOME_COLLECTION_URI + "/hamlet_wrongdoctype.xml"); } } - - @ClassRule - public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer( - propertiesBuilder() - .set(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, "auto") - .build(), - true, - true); - - @BeforeClass - public static void startup() throws Exception { - //create the collections we need for these tests - createTestCollections(); - } - - @AfterClass - public static void shutdown() throws Exception { - removeTestCollections(); - } - - private static void createTestCollections() throws Exception { - final BrokerPool pool = existEmbeddedServer.getBrokerPool(); - final TransactionManager transact = pool.getTransactionManager(); - - try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); - final Txn txn = transact.beginTransaction()) { - - /** create necessary collections if they dont exist */ - Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); - testCollection.getPermissions().setOwner(GUEST_DB_USER); - broker.saveCollection(txn, testCollection); - - Collection col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_DTD_COLLECTION)); - col.getPermissions().setOwner(GUEST_DB_USER); - broker.saveCollection(txn, col); - - col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_XSD_COLLECTION)); - col.getPermissions().setOwner(GUEST_DB_USER); - broker.saveCollection(txn, col); - - col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION)); - col.getPermissions().setOwner(GUEST_DB_USER); - broker.saveCollection(txn, col); - - transact.commit(txn); - } - } - - private static void removeTestCollections() throws Exception { - final BrokerPool pool = existEmbeddedServer.getBrokerPool(); - final TransactionManager transact = pool.getTransactionManager(); - - try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); - final Txn txn = transact.beginTransaction()) { - - /** create necessary collections if they dont exist */ - Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); - broker.removeCollection(txn, testCollection); - - transact.commit(txn); - } - } } diff --git a/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_WithValidation_Test.java b/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_WithValidation_Test.java index ee6fea291ab..0b8bd48c2ed 100644 --- a/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_WithValidation_Test.java +++ b/exist-core/src/test/java/org/exist/validation/DatabaseInsertResources_WithValidation_Test.java @@ -21,10 +21,7 @@ */ package org.exist.validation; -import java.io.*; -import java.net.URL; -import java.util.Optional; - +import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; import org.exist.collections.Collection; import org.exist.storage.BrokerPool; import org.exist.storage.DBBroker; @@ -32,45 +29,99 @@ import org.exist.storage.txn.Txn; import org.exist.test.ExistEmbeddedServer; import org.exist.util.XMLReaderObjectFactory; -import org.apache.commons.io.input.UnsynchronizedByteArrayInputStream; import org.exist.util.io.InputStreamUtil; import org.exist.xmldb.XmldbURI; - import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Optional; + import static java.nio.charset.StandardCharsets.UTF_8; import static org.exist.TestUtils.*; -import static org.exist.util.PropertiesBuilder.propertiesBuilder; import static org.exist.samples.Samples.SAMPLES; +import static org.exist.util.PropertiesBuilder.propertiesBuilder; /** - * Insert documents for validation tests. + * Insert documents for validation tests. * * @author Dannes Wessels (dizzzz@exist-db.org) */ public class DatabaseInsertResources_WithValidation_Test { + @ClassRule + public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer( + propertiesBuilder() + .set(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, "auto") + .build(), + true, + true); private final static String TEST_COLLECTION = "testValidationInsert"; - private final static String VALIDATION_HOME_COLLECTION_URI = "/db/" + TEST_COLLECTION + "/" + TestTools.VALIDATION_HOME_COLLECTION; - + + @BeforeClass + public static void startup() throws Exception { + createTestCollections(); + } + + @AfterClass + public static void shutdown() throws Exception { + removeTestCollections(); + } + + private static void createTestCollections() throws Exception { + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); + final TransactionManager transact = pool.getTransactionManager(); + + try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); + final Txn txn = transact.beginTransaction()) { + + + /** create nessecary collections if they dont exist */ + final Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); + testCollection.getPermissions().setOwner(GUEST_DB_USER); + broker.saveCollection(txn, testCollection); + + final Collection col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION)); + col.getPermissions().setOwner(GUEST_DB_USER); + broker.saveCollection(txn, col); + + transact.commit(txn); + } + } + + private static void removeTestCollections() throws Exception { + final BrokerPool pool = existEmbeddedServer.getBrokerPool(); + final TransactionManager transact = pool.getTransactionManager(); + + try (final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); + final Txn txn = transact.beginTransaction()) { + + final Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); + broker.removeCollection(txn, testCollection); + + transact.commit(txn); + } + } + /** * Test for inserting hamlet.xml, while validating using default registered * DTD set in system catalog. - * + *

* First the string - * + * * needs to be modified into - * + * */ @Test public void validDocumentSystemCatalog() throws IOException { String hamletWithValid = getHamletXml(); hamletWithValid = hamletWithValid.replaceAll("\\Q\\E", - "" ); + ""); TestTools.insertDocumentToURL( new UnsynchronizedByteArrayInputStream(hamletWithValid.getBytes(UTF_8)), @@ -91,86 +142,33 @@ private URL getPlayDtdUrl() { /** * Test for inserting hamlet.xml, while validating using default registered * DTD set in system catalog. - * + *

* First the string - * + * * needs to be modified into - * - * + * + *

* Additionally all "TITLE" elements are renamed to "INVALIDTITLE" */ @Test public void invalidDocumentSystemCatalog() throws IOException { String hamletWithInvalid = getHamletXml(); hamletWithInvalid = hamletWithInvalid.replaceAll("\\Q\\E", - "" ); + ""); - hamletWithInvalid = hamletWithInvalid.replaceAll("TITLE", "INVALIDTITLE" ); + hamletWithInvalid = hamletWithInvalid.replaceAll("TITLE", "INVALIDTITLE"); try { TestTools.insertDocumentToURL( new UnsynchronizedByteArrayInputStream(hamletWithInvalid.getBytes(UTF_8)), - "xmldb:exist://" + VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION + "/hamlet_invalid.xml" - + "xmldb:exist://" + VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION + "/hamlet_invalid.xml" + ); } catch (final IOException ioe) { //TODO consider how to get better error handling than matching on exception strings! - if(!ioe.getCause().getMessage().matches(".*Element type \"INVALIDTITLE\" must be declared.*")){ + if (!ioe.getCause().getMessage().matches(".*Element type \"INVALIDTITLE\" must be declared.*")) { throw ioe; } } } - - @ClassRule - public static final ExistEmbeddedServer existEmbeddedServer = new ExistEmbeddedServer( - propertiesBuilder() - .set(XMLReaderObjectFactory.PROPERTY_VALIDATION_MODE, "auto") - .build(), - true, - true); - - @BeforeClass - public static void startup() throws Exception { - createTestCollections(); - } - - @AfterClass - public static void shutdown() throws Exception { - removeTestCollections(); - } - - private static void createTestCollections() throws Exception { - final BrokerPool pool = existEmbeddedServer.getBrokerPool(); - final TransactionManager transact = pool.getTransactionManager(); - - try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); - final Txn txn = transact.beginTransaction()) { - - - /** create nessecary collections if they dont exist */ - Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); - testCollection.getPermissions().setOwner(GUEST_DB_USER); - broker.saveCollection(txn, testCollection); - - Collection col = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI + "/" + TestTools.VALIDATION_TMP_COLLECTION)); - col.getPermissions().setOwner(GUEST_DB_USER); - broker.saveCollection(txn, col); - - transact.commit(txn); - } - } - - private static void removeTestCollections() throws Exception { - final BrokerPool pool = existEmbeddedServer.getBrokerPool(); - final TransactionManager transact = pool.getTransactionManager(); - - try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().authenticate(ADMIN_DB_USER, ADMIN_DB_PWD))); - final Txn txn = transact.beginTransaction()) { - - Collection testCollection = broker.getOrCreateCollection(txn, XmldbURI.create(VALIDATION_HOME_COLLECTION_URI)); - broker.removeCollection(txn, testCollection); - - transact.commit(txn); - } - } } diff --git a/exist-core/src/test/java/org/exist/validation/DtdEntityTest.java b/exist-core/src/test/java/org/exist/validation/DtdEntityTest.java index a12e4e18a16..32a8c486b7c 100644 --- a/exist-core/src/test/java/org/exist/validation/DtdEntityTest.java +++ b/exist-core/src/test/java/org/exist/validation/DtdEntityTest.java @@ -21,17 +21,20 @@ */ package org.exist.validation; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.Assert.*; - import org.exist.test.ExistXmldbEmbeddedServer; -import org.junit.*; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Test; import org.xmldb.api.base.Collection; import org.xmldb.api.base.XMLDBException; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * Small test to show than entities are required to be resolved. - * + * * @author wessels */ public class DtdEntityTest { @@ -43,7 +46,7 @@ public class DtdEntityTest { public void loadWithEntities() throws XMLDBException { final String input = "first empty: ∅ then trade: ™ "; - try (Collection col = existEmbeddedServer.createCollection(existEmbeddedServer.getRoot(), "entity")) { + try (final Collection col = existEmbeddedServer.createCollection(existEmbeddedServer.getRoot(), "entity")) { ExistXmldbEmbeddedServer.storeResource(col, "docname.xml", input.getBytes()); // should throw XMLDBException @@ -57,13 +60,14 @@ public void loadWithEntities() throws XMLDBException { fail("Should have thrown XMLDBException"); } - @Test @Ignore("Entity resolve bug") + @Test + @Ignore("Entity resolve bug") public void bugloadWithEntities() throws XMLDBException { final String input = "" + "" + "first empty: ∅ then trade: ™ "; - try (Collection col = existEmbeddedServer.createCollection(existEmbeddedServer.getRoot(), "entity")) { + try (final Collection col = existEmbeddedServer.createCollection(existEmbeddedServer.getRoot(), "entity")) { ExistXmldbEmbeddedServer.storeResource(col, "docname.xml", input.getBytes(UTF_8)); // should throw XMLDBException diff --git a/exist-core/src/test/java/org/exist/validation/GrammarPoolTest.java b/exist-core/src/test/java/org/exist/validation/GrammarPoolTest.java new file mode 100644 index 00000000000..c615f575053 --- /dev/null +++ b/exist-core/src/test/java/org/exist/validation/GrammarPoolTest.java @@ -0,0 +1,134 @@ +/* + * eXist-db Open Source Native XML Database + * Copyright (C) 2001 The eXist-db Authors + * + * info@exist-db.org + * http://www.exist-db.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +package org.exist.validation; + +import org.apache.xerces.impl.xs.XMLSchemaLoader; +import org.apache.xerces.xni.grammars.Grammar; +import org.apache.xerces.xni.grammars.XMLGrammarDescription; +import org.apache.xerces.xni.grammars.XMLGrammarLoader; +import org.apache.xerces.xni.parser.XMLInputSource; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import static org.junit.jupiter.api.Assertions.*; + +class GrammarPoolTest { + + private final String TEMPLATE = """ + + + + + + + + + + + + + + + + """; + + private GrammarPool grammarPool; + + @BeforeEach + void prepare() { + grammarPool = new GrammarPool(10, 10); + } + + Grammar constructFromText(final String systemId, final String content) { + try (final InputStream resourceAsStream = new ByteArrayInputStream(content.getBytes())) { + assertNotNull(resourceAsStream); + return loadGrammar(systemId, resourceAsStream); + + } catch (final IOException ex) { + fail(ex.getMessage()); + } + return null; + } + + private Grammar loadGrammar(final String systemId, final InputStream resourceAsStream) throws IOException { + final XMLInputSource inputSource = new XMLInputSource(null, systemId, null, resourceAsStream, null); + final XMLGrammarLoader schemaLoader = new XMLSchemaLoader(); + return schemaLoader.loadGrammar(inputSource); + } + + @Test + void simpleCache() { + final Grammar xsd = constructFromText("systemid", TEMPLATE); + + // check empty + assertEquals(0, grammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA).length); + + // add one + grammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, new Grammar[]{xsd}); + + // check one + assertEquals(1, grammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA).length); + + // add same one again + grammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, new Grammar[]{xsd}); + + // still one + assertEquals(1, grammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA).length); + + // make cache empty + grammarPool.clear(); + + // check empty + assertEquals(0, grammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA).length); + } + + @Test + void fillCache() throws InterruptedException { + + // fill cache + for (int i = 0; i < 200; i++) { + final String txt = TEMPLATE.replace("TEMPLATE", "" + i); + final Grammar xsd = constructFromText("systemid", txt); + grammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, new Grammar[]{xsd}); + } + + // give cache time to work on cleanup + Thread.sleep(250); + + // only 5 should be cached + assertEquals(10, grammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA).length); + + // make cache empty + grammarPool.clear(); + + // check empty + assertEquals(0, grammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA).length); + } + +} \ No newline at end of file diff --git a/exist-core/src/test/java/org/exist/validation/TestTools.java b/exist-core/src/test/java/org/exist/validation/TestTools.java index 147b9a23d54..83dc016b73f 100644 --- a/exist-core/src/test/java/org/exist/validation/TestTools.java +++ b/exist-core/src/test/java/org/exist/validation/TestTools.java @@ -38,7 +38,7 @@ import java.net.URLConnection; /** - * A set of helper methods for the validation tests. + * A set of helper methods for the validation tests. * * @author Dannes Wessels (dizzzz@exist-db.org) */ @@ -48,12 +48,12 @@ public class TestTools { public final static String VALIDATION_DTD_COLLECTION = "dtd"; public final static String VALIDATION_XSD_COLLECTION = "xsd"; public final static String VALIDATION_TMP_COLLECTION = "tmp"; - + /** * - * @param document File to be uploaded - * @param target Target URL (e.g. xmldb:exist:///db/collection/document.xml) - * @throws java.lang.Exception Oops..... + * @param document File to be uploaded + * @param target Target URL (e.g. xmldb:exist:///db/collection/document.xml) + * @throws java.lang.Exception Oops..... */ public static void insertDocumentToURL(final InputStream document, final String target) throws IOException { final URL url = new URL(target); @@ -65,7 +65,7 @@ public static void insertDocumentToURL(final InputStream document, final String public static Sequence executeQuery(final BrokerPool pool, final String query) throws EXistException, PermissionDeniedException, XPathException { final XQuery xquery = pool.getXQueryService(); - try(final DBBroker broker = pool.getBroker()) { + try (final DBBroker broker = pool.getBroker()) { return xquery.execute(broker, query, null); } } diff --git a/exist-distribution/src/main/config/conf.xml b/exist-distribution/src/main/config/conf.xml index c266900c2ec..026734ebf05 100644 --- a/exist-distribution/src/main/config/conf.xml +++ b/exist-distribution/src/main/config/conf.xml @@ -25,6 +25,8 @@ serializer transformer validation + entity-resolver + grammar-cache xquery builtin-modules module @@ -902,6 +904,22 @@ + + +