Skip to content

Commit ce3bebf

Browse files
committed
Make use of XMLUtils.newSchemaFactory() and fix up validation based on GeoWebCache 2.0.0
1 parent 3a26cd7 commit ce3bebf

13 files changed

Lines changed: 443 additions & 39 deletions

File tree

geowebcache/core/src/main/java/org/geowebcache/config/XMLConfiguration.java

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import java.io.FileNotFoundException;
2222
import java.io.IOException;
2323
import java.io.InputStream;
24+
import java.io.OutputStream;
2425
import java.io.OutputStreamWriter;
26+
import java.io.PrintWriter;
2527
import java.io.UnsupportedEncodingException;
2628
import java.net.MalformedURLException;
2729
import java.net.URL;
@@ -49,6 +51,7 @@
4951
import javax.xml.transform.TransformerFactoryConfigurationError;
5052
import javax.xml.transform.dom.DOMResult;
5153
import javax.xml.transform.dom.DOMSource;
54+
import javax.xml.transform.stream.StreamResult;
5255
import javax.xml.transform.stream.StreamSource;
5356
import javax.xml.validation.Schema;
5457
import javax.xml.validation.SchemaFactory;
@@ -118,6 +121,10 @@ public class XMLConfiguration
118121

119122
public static final String DEFAULT_CONFIGURATION_FILE_NAME = "geowebcache.xml";
120123

124+
public static final String SCHEMA_NAMESPACE_PREFIX = "http://geowebcache.org/schema/";
125+
126+
public static final String DEFAULT_SCHEMA_RESOURCE = "geowebcache.xsd";
127+
121128
private static Logger log = Logging.getLogger(XMLConfiguration.class.getName());
122129

123130
/** Web app context, used to look up {@link XMLConfigurationProvider}s. */
@@ -630,14 +637,12 @@ private static Node checkAndTransform(Document doc) throws ConfigurationExceptio
630637
Node rootNode = doc.getDocumentElement();
631638

632639
// debugPrint(rootNode);
633-
634640
if (!rootNode.getNodeName().equals("gwcConfiguration")) {
635641
log.config("The configuration file is of the pre 1.0 type, trying to convert.");
636642
rootNode = applyTransform(rootNode, "geowebcache_pre10.xsl").getFirstChild();
637643
}
638644

639645
// debugPrint(rootNode);
640-
641646
if (rootNode.getNamespaceURI().equals("http://geowebcache.org/schema/1.0.0")) {
642647
log.config("Updating configuration from 1.0.0 to 1.0.1");
643648
rootNode = applyTransform(rootNode, "geowebcache_100.xsl").getFirstChild();
@@ -717,6 +722,11 @@ private static Node checkAndTransform(Document doc) throws ConfigurationExceptio
717722
rootNode = applyTransform(rootNode, "geowebcache_151.xsl").getFirstChild();
718723
}
719724

725+
if (!rootNode.getNamespaceURI().equals("http://geowebcache.org/schema/2.0.0")) {
726+
log.config("Updating configuration to 2.0.0");
727+
rootNode = applyTransform(rootNode, "geowebcache_200.xsl").getFirstChild();
728+
}
729+
720730
// Check again after transform
721731
if (!rootNode.getNodeName().equals("gwcConfiguration")) {
722732
log.log(Level.SEVERE, "Unable to parse file, expected gwcConfiguration at root after transform.");
@@ -727,8 +737,8 @@ private static Node checkAndTransform(Document doc) throws ConfigurationExceptio
727737
validate(rootNode);
728738
log.config("TileLayerConfiguration file validated fine.");
729739
} catch (SAXException e) {
730-
log.warning("GWC configuration validation error: " + e.getMessage());
731-
log.warning(
740+
log.fine("GWC configuration validation error: " + e.getMessage());
741+
log.fine(
732742
"Will try to use configuration anyway. Please check the order of declared elements against the schema.");
733743
} catch (IOException e) {
734744
throw new RuntimeException(e.getMessage(), e);
@@ -740,14 +750,14 @@ private static Node checkAndTransform(Document doc) throws ConfigurationExceptio
740750

741751
static void validate(Node rootNode) throws SAXException, IOException {
742752
// Perform validation
743-
// TODO dont know why this one suddenly failed to look up, revert to
744-
// XMLConstants.W3C_XML_SCHEMA_NS_URI
745-
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
746-
// We normally don't need access to external schemas
753+
SchemaFactory factory = XMLUtils.newSchemaFactory(XMLConstants.W3C_XML_SCHEMA_NS_URI);
754+
// We do not need access to external schemas
747755
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_SCHEMA, "");
748756
factory.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, "");
749757
try (InputStream is = XMLConfiguration.class.getResourceAsStream("geowebcache.xsd")) {
750-
758+
if (is == null) {
759+
throw new IOException("Could not load schema resource 'geowebcache.xsd'");
760+
}
751761
Schema schema = factory.newSchema(new StreamSource(is));
752762
Validator validator = schema.newValidator();
753763

@@ -1466,4 +1476,17 @@ public void deinitialize() throws Exception {
14661476
this.layers = null;
14671477
this.gwcConfig = null;
14681478
}
1479+
1480+
/** Print a DOM tree to an output stream or if there is an exception while doing so, print the stack trace. */
1481+
public static void printDom(Node dom, OutputStream os) {
1482+
Transformer trans;
1483+
PrintWriter w = new PrintWriter(os);
1484+
try {
1485+
trans = XMLUtils.newTransformer(); // XMLUtils.newTransformer()
1486+
trans.transform(new DOMSource(dom), new StreamResult(new OutputStreamWriter(os)));
1487+
} catch (TransformerException e) {
1488+
w.println("An error ocurred while transforming the given DOM:");
1489+
e.printStackTrace(w);
1490+
}
1491+
}
14691492
}

geowebcache/core/src/main/resources/org/geowebcache/config/geowebcache.xsd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0"?>
22
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xml="http://www.w3.org/XML/1998/namespace"
3-
targetNamespace="http://geowebcache.org/schema/1.28.0" xmlns:gwc="http://geowebcache.org/schema/1.28.0"
4-
elementFormDefault="qualified" version="1.28.0">
3+
targetNamespace="http://geowebcache.org/schema/2.0.0" xmlns:gwc="http://geowebcache.org/schema/2.0.0"
4+
elementFormDefault="qualified" version="2.0.0">
55

66
<xs:element name="gwcConfiguration">
77
<xs:annotation>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xsl:stylesheet xmlns:gwc="http://geowebcache.org/schema/1.6.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
3+
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
4+
5+
<xsl:template match="node()|*">
6+
<xsl:copy>
7+
<xsl:apply-templates/>
8+
</xsl:copy>
9+
</xsl:template>
10+
11+
<xsl:template match="/|comment()|processing-instruction()">
12+
<xsl:copy>
13+
<xsl:apply-templates/>
14+
</xsl:copy>
15+
</xsl:template>
16+
17+
<xsl:template match="*">
18+
<xsl:element name="{local-name()}">
19+
<xsl:apply-templates select="@*|node()"/>
20+
</xsl:element>
21+
</xsl:template>
22+
23+
<xsl:template match="@*">
24+
<xsl:attribute name="{local-name()}">
25+
<xsl:value-of select="."/>
26+
</xsl:attribute>
27+
</xsl:template>
28+
29+
<xsl:template match="gwc:keyword">
30+
<string><xsl:apply-templates/></string>
31+
</xsl:template>
32+
33+
<xsl:template match="gwc:gwcConfiguration">
34+
<gwcConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
35+
xmlns="http://geowebcache.org/schema/2.0.0"
36+
xsi:schemaLocation="http://geowebcache.org/schema/2.0.0 http://geowebcache.org/schema/2.0.0/geowebcache.xsd">
37+
<xsl:apply-templates/>
38+
</gwcConfiguration>
39+
</xsl:template>
40+
41+
</xsl:stylesheet>

geowebcache/core/src/test/java/org/geowebcache/config/ServerConfigurationTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
public class ServerConfigurationTest {
3838

39-
private static final String VERSION_PATTERN = "1(\\.\\d+)+(\\-\\w+)*";
39+
private static final String VERSION_PATTERN = "2(\\.\\d+)+(\\-\\w+)*";
4040

4141
ServerConfiguration config;
4242

geowebcache/core/src/test/java/org/geowebcache/config/XMLConfigurationBackwardsCompatibilityTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import javax.xml.transform.TransformerFactory;
3030
import javax.xml.transform.dom.DOMSource;
3131
import javax.xml.transform.stream.StreamResult;
32+
import org.geotools.xml.XMLUtils;
3233
import org.geowebcache.GeoWebCacheException;
3334
import org.geowebcache.config.meta.ServiceInformation;
3435
import org.geowebcache.filter.request.RequestFilter;
@@ -45,7 +46,9 @@ public class XMLConfigurationBackwardsCompatibilityTest {
4546

4647
public static final String GWC_125_CONFIG_FILE = "geowebcache_125.xml";
4748

48-
public static final String LATEST_FILENAME = "geowebcache_130.xml";
49+
public static final String GWC_130_CONFIG_FILE = "geowebcache_130.xml";
50+
51+
public static final String LATEST_FILENAME = "geowebcache_200.xml";
4952

5053
@Test
5154
public void testLoadPre10() throws Exception {
@@ -227,14 +230,14 @@ private XMLConfiguration loadConfig(String fileName) throws Exception {
227230

228231
/** Utility method to print out a dom. */
229232
protected void print(Document dom) throws Exception {
230-
TransformerFactory txFactory = TransformerFactory.newInstance();
233+
TransformerFactory txFactory = XMLUtils.newTransformerFactory();
231234
try {
232235
txFactory.setAttribute("{http://xml.apache.org/xalan}indent-number", Integer.valueOf(2));
233236
} catch (Exception e) {
234237
// some
235238
}
236239

237-
Transformer tx = txFactory.newTransformer();
240+
Transformer tx = XMLUtils.newTransformer(txFactory);
238241
tx.setOutputProperty(OutputKeys.METHOD, "xml");
239242
tx.setOutputProperty(OutputKeys.INDENT, "yes");
240243

geowebcache/core/src/test/java/org/geowebcache/config/XMLConfigurationTest.java

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import java.io.FileInputStream;
4141
import java.io.FilterOutputStream;
4242
import java.io.IOException;
43+
import java.io.InputStream;
4344
import java.io.OutputStream;
4445
import java.net.URL;
4546
import java.util.ArrayList;
@@ -81,6 +82,7 @@
8182
import org.mockito.Mockito;
8283
import org.springframework.context.ApplicationContext;
8384
import org.springframework.web.context.WebApplicationContext;
85+
import org.w3c.dom.Node;
8486
import org.xml.sax.SAXParseException;
8587

8688
public class XMLConfigurationTest {
@@ -115,6 +117,15 @@ public void setUp() throws Exception {
115117
config.afterPropertiesSet();
116118
}
117119

120+
@Test
121+
public void testValidateVersionedSchemaFromNamespace() throws Exception {
122+
try (InputStream xml = XMLConfigurationTest.class.getResourceAsStream("geowebcache-config-env.xml")) {
123+
assertNotNull(xml);
124+
Node document = XMLConfiguration.loadDocument(xml);
125+
XMLConfiguration.validate(document);
126+
}
127+
}
128+
118129
@Test
119130
public void testAddLayer() throws Exception {
120131
int count = config.getLayerCount();
@@ -477,10 +488,17 @@ public void testOverrideGridSetDefaults() throws Exception {
477488
overrideDescription.contains("OVERRIDE"));
478489
}
479490

491+
/**
492+
* GeoWebCache 1.8.0 default to one disabled blob store
493+
*
494+
* @throws Exception
495+
*/
480496
@Test
481-
public void testNoBlobStores() throws Exception {
497+
public void testSingleDisabledBlobStores() throws Exception {
482498
assertNotNull(config.getBlobStores());
483-
assertTrue(config.getBlobStores().isEmpty());
499+
assertEquals("single blobstore", 1, config.getBlobStoreCount());
500+
BlobStoreInfo store = config.getBlobStores().get(0);
501+
assertFalse("single disabled blobstore", store.isEnabled());
484502
}
485503

486504
@Test
@@ -499,6 +517,8 @@ public void testAddBlobStores() throws Exception {
499517
store2.setFileSystemBlockSize(512);
500518
store2.setBaseDirectory("/tmp/test2");
501519

520+
int baseline = config.getBlobStoreCount();
521+
502522
config.addBlobStore(store1);
503523
config.addBlobStore(store2);
504524

@@ -516,12 +536,12 @@ public void testAddBlobStores() throws Exception {
516536

517537
List<BlobStoreInfo> stores = config2.getBlobStores();
518538
assertNotNull(stores);
519-
assertEquals(2, stores.size());
520-
assertNotSame(store1, stores.get(0));
521-
assertEquals(store1, stores.get(0));
539+
assertEquals(baseline + 2, stores.size());
540+
assertNotSame(store1, stores.get(baseline + 0));
541+
assertEquals(store1, stores.get(baseline + 0));
522542

523-
assertNotSame(store2, stores.get(1));
524-
assertEquals(store2, stores.get(1));
543+
assertNotSame(store2, stores.get(baseline + 1));
544+
assertEquals(store2, stores.get(baseline + 1));
525545
}
526546

527547
@Test
@@ -558,6 +578,8 @@ public void close() throws IOException {
558578
config = new XMLConfiguration(null, resourceProvider);
559579
config.setGridSetBroker(gridSetBroker);
560580

581+
int initialCount = config.getBlobStoreCount();
582+
561583
FileBlobStoreInfo store1 = new FileBlobStoreInfo();
562584
store1.setName("store1");
563585
store1.setDefault(true);
@@ -566,9 +588,9 @@ public void close() throws IOException {
566588
store1.setBaseDirectory("/tmp/test");
567589

568590
assertThrows(ConfigurationPersistenceException.class, () -> config.addBlobStore(store1));
569-
assertEquals(0, config.getBlobStoreCount());
570-
GeoWebCacheConfiguration configuration = config.loadConfiguration();
571-
assertTrue("store shouldn't be saved", configuration.getBlobStores().isEmpty());
591+
assertEquals(1, config.getBlobStoreCount());
592+
config.loadConfiguration();
593+
assertEquals("store shouldn't be saved", initialCount, config.getBlobStoreCount());
572594
}
573595

574596
/**
@@ -606,12 +628,20 @@ public void testAddBlobStoreExceptionFromListener() throws Exception {
606628

607629
private void assertAddBlobStoreFails(FileBlobStoreInfo store, Class<? extends Exception> expectedCause)
608630
throws ConfigurationException {
631+
609632
ConfigurationPersistenceException expected;
633+
634+
int baseline = config.getBlobStoreCount();
635+
610636
expected = assertThrows(ConfigurationPersistenceException.class, () -> config.addBlobStore(store));
611637
assertThat(expected.getCause(), instanceOf(expectedCause));
612-
assertEquals(0, config.getBlobStoreCount());
638+
639+
assertEquals(baseline, config.getBlobStoreCount());
613640
GeoWebCacheConfiguration configuration = config.loadConfiguration();
614-
assertTrue("store shouldn't be saved", configuration.getBlobStores().isEmpty());
641+
assertEquals(
642+
"store shouldn't be saved",
643+
baseline,
644+
configuration.getBlobStores().size());
615645
}
616646

617647
/**
@@ -643,28 +673,31 @@ public void testModifyBlobStoreExceptionFromListener() throws Exception {
643673

644674
// note, I'm not sure why XMLConfiguration.addBlobStore() only rolls-back on UnsuitableStorageException and not
645675
// on IOException or GeoWebCacheException
676+
646677
// doThrow(new IOException("fake")).when(listener).handleModifyBlobStore(Mockito.any());
647678
// assertModifyBlobStoreFails(original, IOException.class);
648-
//
679+
649680
// doThrow(new GeoWebCacheException("fake")).when(listener).handleModifyBlobStore(Mockito.any());
650681
// assertModifyBlobStoreFails(original, GeoWebCacheException.class);
651682
}
652683

653684
private void assertModifyBlobStoreFails(FileBlobStoreInfo original, Class<? extends Exception> expectedCause)
654685
throws ConfigurationException {
655686

687+
int baseline = config.getBlobStoreCount();
688+
656689
FileBlobStoreInfo modified = (FileBlobStoreInfo) original.clone();
657690
modified.setBaseDirectory("/tmp/test2");
658691

659-
assertEquals(1, config.getBlobStoreCount());
692+
assertEquals(baseline, config.getBlobStoreCount());
660693

661694
ConfigurationPersistenceException expected;
662695
expected = assertThrows(ConfigurationPersistenceException.class, () -> config.modifyBlobStore(modified));
663696
assertThat(expected.getCause(), instanceOf(expectedCause));
664697
GeoWebCacheConfiguration reloaded = config.loadConfiguration();
665-
assertEquals(1, reloaded.getBlobStores().size());
698+
assertEquals(baseline, reloaded.getBlobStores().size());
666699

667-
BlobStoreInfo stored = reloaded.getBlobStores().get(0);
700+
BlobStoreInfo stored = reloaded.getBlobStores().get(baseline - 1);
668701
assertEquals("store shouldn't be saved", original, stored);
669702
}
670703

geowebcache/core/src/test/resources/org/geowebcache/config/geowebcache-config-env.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<gwcConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xmlns="http://geowebcache.org/schema/1.25.0"
4-
xsi:schemaLocation="http://geowebcache.org/schema/1.25.0 https://raw.githubusercontent.com/GeoWebCache/geowebcache/refs/heads/main/geowebcache/core/src/main/resources/org/geowebcache/config/geowebcache_1250.xsd">
3+
xmlns="http://geowebcache.org/schema/2.0.0"
4+
xsi:schemaLocation="http://geowebcache.org/schema/2.0.0 https://raw.githubusercontent.com/GeoWebCache/geowebcache/refs/heads/main/geowebcache/core/src/main/resources/org/geowebcache/config/geowebcache_200.xsd">
55
<!--
66
Sample configuration with environmant variable placeholders
77
for the global and per-layer http username and password

geowebcache/core/src/test/resources/org/geowebcache/config/geowebcache_190.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<gwcConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
33
xmlns="http://geowebcache.org/schema/1.9.0"
44
xsi:schemaLocation="http://geowebcache.org/schema/1.9.0 http://geowebcache.org/schema/1.9.0/geowebcache.xsd">
5-
<version>1.8.0</version>
5+
<version>1.9.0</version>
66
<backendTimeout>120</backendTimeout>
77
<serviceInformation>
88
<title>GeoWebCache</title>

0 commit comments

Comments
 (0)