2222import java .io .InputStream ;
2323import java .io .OutputStream ;
2424import java .net .URL ;
25+ import java .util .HashSet ;
26+ import java .util .List ;
27+ import java .util .Set ;
28+ import java .util .TreeSet ;
2529import javax .xml .namespace .QName ;
2630import org .apache .commons .io .IOUtils ;
2731import org .geotools .api .feature .type .FeatureType ;
2832import org .geotools .api .referencing .crs .CoordinateReferenceSystem ;
2933import org .geotools .data .wfs .internal .parsers .EmfAppSchemaParser ;
3034import org .geotools .http .HTTPResponse ;
3135import org .geotools .ows .ServiceException ;
36+ import org .geotools .util .URLs ;
3237import org .geotools .xsd .Configuration ;
3338import org .xml .sax .EntityResolver ;
3439import org .xml .sax .InputSource ;
@@ -92,12 +97,49 @@ private EntityResolver getTempFileEntityResolver(EntityResolver resolver, File t
9297 }
9398
9499 private static class TempEntityResolver implements EntityResolver {
95- EntityResolver delegate ;
96- File tempSchema ;
100+ private final EntityResolver delegate ;
101+ private Set < String > tempSchemaURIs ;
97102
98103 public TempEntityResolver (EntityResolver delegate , File tempSchema ) {
99104 this .delegate = delegate ;
100- this .tempSchema = tempSchema ;
105+ URL tempSchemaURL = URLs .fileToUrl (tempSchema );
106+ this .tempSchemaURIs = new HashSet <>(List .of (tempSchemaURL .toExternalForm (), tempSchemaURL .toString ()));
107+ try {
108+ File canonicalFile = tempSchema .getCanonicalFile ();
109+ URL canonicalSchemaURL = URLs .fileToUrl (canonicalFile );
110+ tempSchemaURIs .add (canonicalSchemaURL .toExternalForm ());
111+ tempSchemaURIs .add (canonicalSchemaURL .toString ());
112+ } catch (IOException e ) {
113+ throw new RuntimeException ("Unable to get canonical file for " + tempSchema , e );
114+ }
115+ if (!isFileSystemCaseSensitive (tempSchema )) {
116+ Set <String > insensitive = new TreeSet <>(String .CASE_INSENSITIVE_ORDER );
117+ insensitive .addAll (tempSchemaURIs );
118+ this .tempSchemaURIs = insensitive ;
119+ }
120+ }
121+
122+ static boolean isFileSystemCaseSensitive (File knownFile ) {
123+ if (!knownFile .exists ()) {
124+ throw new IllegalArgumentException ("The specified file does not exist: " + knownFile );
125+ }
126+
127+ // Try to access the same file with a different case
128+ File alteredCase = new File (knownFile .getParentFile (), toggleCase (knownFile .getName ()));
129+ return !alteredCase .exists ();
130+ }
131+
132+ static String toggleCase (String name ) {
133+ char [] chars = name .toCharArray ();
134+ for (int i = 0 ; i < chars .length ; i ++) {
135+ char c = chars [i ];
136+ if (Character .isUpperCase (c )) {
137+ chars [i ] = Character .toLowerCase (c );
138+ } else if (Character .isLowerCase (c )) {
139+ chars [i ] = Character .toUpperCase (c );
140+ }
141+ }
142+ return new String (chars );
101143 }
102144
103145 @ Override
@@ -108,9 +150,7 @@ public InputSource resolveEntity(String publicId, String systemId) throws SAXExc
108150 }
109151
110152 protected boolean isTempSchema (String systemId ) {
111- // let it go
112- if (systemId .equalsIgnoreCase ("file:" + tempSchema .getAbsolutePath ())) return true ;
113- return false ;
153+ return tempSchemaURIs .contains (systemId );
114154 }
115155 }
116156
0 commit comments