~ubuntu-branches/ubuntu/saucy/commons-configuration/saucy

« back to all changes in this revision

Viewing changes to src/java/org/apache/commons/configuration/resolver/CatalogResolver.java

  • Committer: Package Import Robot
  • Author(s): Emmanuel Bourg
  • Date: 2013-07-01 16:29:44 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20130701162944-98waq5gogha5gpn1
Tags: 1.9-1
* New upstream release
* debian/control:
  - Updated Standards-Version to 3.9.4 (no changes)
  - Use canonical URLs for the Vcs-* fields
  - Added new build dependencies (libjavacc-maven-plugin-java, junit4)
  - Upgraded the dependency on the Servlet API (2.5 -> 3.0)
  - Removed the dependency on the Activation Framework (glassfish-activation)
  - Replaced the dependency on glassfish-mail with libgnumail-java
  - Removed the unused dependencies:
    liblog4j1.2-java-doc, libmaven-assembly-plugin-java
  - Replaced the dependency on libcommons-jexl-java by libcommons-jexl2-java
* debian/watch: Changed to point the official Apache distribution server
* Removed the obsolete file debian/ant.properties
* Installed the upstream changelog in the binary packages
* Added the report plugins to maven.ignoreRules
* Added the classpath attribute to the jar manifest

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 * contributor license agreements.  See the NOTICE file distributed with
4
 
 * this work for additional information regarding copyright ownership.
5
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 * (the "License"); you may not use this file except in compliance with
7
 
 * the License.  You may obtain a copy of the License at
8
 
 *
9
 
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 
 *
11
 
 * Unless required by applicable law or agreed to in writing, software
12
 
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 * See the License for the specific language governing permissions and
15
 
 * limitations under the License.
16
 
 */
17
 
package org.apache.commons.configuration.resolver;
18
 
 
19
 
import org.xml.sax.EntityResolver;
20
 
import org.xml.sax.InputSource;
21
 
import org.xml.sax.SAXException;
22
 
import org.apache.xml.resolver.CatalogException;
23
 
import org.apache.xml.resolver.readers.CatalogReader;
24
 
import org.apache.commons.logging.Log;
25
 
import org.apache.commons.logging.LogFactory;
26
 
import org.apache.commons.configuration.FileSystem;
27
 
import org.apache.commons.configuration.ConfigurationException;
28
 
import org.apache.commons.configuration.ConfigurationUtils;
29
 
import org.apache.commons.lang.text.StrSubstitutor;
30
 
 
31
 
import java.io.InputStream;
32
 
import java.io.IOException;
33
 
import java.net.FileNameMap;
34
 
import java.net.URLConnection;
35
 
import java.net.URL;
36
 
import java.util.Vector;
37
 
 
38
 
/**
39
 
 * Thin wrapper around xml commons CatalogResolver to allow list of catalogs
40
 
 * to be provided.
41
 
 * @author <a
42
 
 * href="http://commons.apache.org/configuration/team-list.html">Commons
43
 
 * Configuration team</a>
44
 
 * @since 1.7
45
 
 * @version $Id: CatalogResolver.java 952631 2010-06-08 12:09:29Z sebb $
46
 
 */
47
 
public class CatalogResolver implements EntityResolver
48
 
{
49
 
    /**
50
 
     * Debug everything.
51
 
     */
52
 
    private static final int DEBUG_ALL = 9;
53
 
 
54
 
    /**
55
 
     * Normal debug setting.
56
 
     */
57
 
    private static final int DEBUG_NORMAL = 4;
58
 
 
59
 
    /**
60
 
     * Debug nothing.
61
 
     */
62
 
    private static final int DEBUG_NONE = 0;
63
 
 
64
 
    /**
65
 
     * The CatalogManager
66
 
     */
67
 
    protected CatalogManager manager = new CatalogManager();
68
 
 
69
 
    /**
70
 
     * The FileSystem in use.
71
 
     */
72
 
    protected FileSystem fs = FileSystem.getDefaultFileSystem();
73
 
 
74
 
    /**
75
 
     * The CatalogResolver
76
 
     */
77
 
    private org.apache.xml.resolver.tools.CatalogResolver resolver;
78
 
 
79
 
    /**
80
 
     * Stores the logger.
81
 
     */
82
 
    private Log log;
83
 
 
84
 
    /**
85
 
     * Constructs the CatalogResolver
86
 
     */
87
 
    public CatalogResolver()
88
 
    {
89
 
        manager.setIgnoreMissingProperties(true);
90
 
        manager.setUseStaticCatalog(false);
91
 
        manager.setFileSystem(fs);
92
 
        setLogger(null);
93
 
    }
94
 
 
95
 
    /**
96
 
     * Set the list of catalog file names
97
 
     *
98
 
     * @param catalogs The delimited list of catalog files.
99
 
     */
100
 
    public void setCatalogFiles(String catalogs)
101
 
    {
102
 
        manager.setCatalogFiles(catalogs);
103
 
    }
104
 
 
105
 
    /**
106
 
     * Set the FileSystem.
107
 
     * @param fileSystem The FileSystem.
108
 
     */
109
 
    public void setFileSystem(FileSystem fileSystem)
110
 
    {
111
 
        this.fs = fileSystem;
112
 
        manager.setFileSystem(fileSystem);
113
 
    }
114
 
 
115
 
    /**
116
 
     * Set the base path.
117
 
     * @param baseDir The base path String.
118
 
     */
119
 
    public void setBaseDir(String baseDir)
120
 
    {
121
 
        manager.setBaseDir(baseDir);
122
 
    }
123
 
 
124
 
    /**
125
 
     * Set the StrSubstitutor.
126
 
     * @param substitutor The StrSubstitutor.
127
 
     */
128
 
    public void setSubstitutor(StrSubstitutor substitutor)
129
 
    {
130
 
        manager.setSubstitutor(substitutor);
131
 
    }
132
 
 
133
 
    /**
134
 
     * Enables debug logging of xml-commons Catalog processing.
135
 
     * @param debug True if debugging should be enabled, false otherwise.
136
 
     */
137
 
    public void setDebug(boolean debug)
138
 
    {
139
 
        if (debug)
140
 
        {
141
 
            manager.setVerbosity(DEBUG_ALL);
142
 
        }
143
 
        else
144
 
        {
145
 
            manager.setVerbosity(DEBUG_NONE);
146
 
        }
147
 
    }
148
 
 
149
 
    /**
150
 
     * Implements the <code>resolveEntity</code> method
151
 
     * for the SAX interface.
152
 
     * <p/>
153
 
     * <p>Presented with an optional public identifier and a system
154
 
     * identifier, this function attempts to locate a mapping in the
155
 
     * catalogs.</p>
156
 
     * <p/>
157
 
     * <p>If such a mapping is found, the resolver attempts to open
158
 
     * the mapped value as an InputSource and return it. Exceptions are
159
 
     * ignored and null is returned if the mapped value cannot be opened
160
 
     * as an input source.</p>
161
 
     * <p/>
162
 
     * <p>If no mapping is found (or an error occurs attempting to open
163
 
     * the mapped value as an input source), null is returned and the system
164
 
     * will use the specified system identifier as if no entityResolver
165
 
     * was specified.</p>
166
 
     *
167
 
     * @param publicId The public identifier for the entity in question.
168
 
     *                 This may be null.
169
 
     * @param systemId The system identifier for the entity in question.
170
 
     *                 XML requires a system identifier on all external entities, so this
171
 
     *                 value is always specified.
172
 
     * @return An InputSource for the mapped identifier, or null.
173
 
     * @throws SAXException if an error occurs.
174
 
     */
175
 
    public InputSource resolveEntity(String publicId, String systemId)
176
 
            throws SAXException
177
 
    {
178
 
        String resolved = getResolver().getResolvedEntity(publicId, systemId);
179
 
 
180
 
        if (resolved != null)
181
 
        {
182
 
            String badFilePrefix = "file://";
183
 
            String correctFilePrefix = "file:///";
184
 
 
185
 
            // Java 5 has a bug when constructing file URLS
186
 
            if (resolved.startsWith(badFilePrefix) && !resolved.startsWith(correctFilePrefix))
187
 
            {
188
 
                resolved = correctFilePrefix + resolved.substring(badFilePrefix.length());
189
 
            }
190
 
 
191
 
            try
192
 
            {
193
 
                InputStream is = fs.getInputStream(null, resolved);
194
 
                InputSource iSource = new InputSource(resolved);
195
 
                iSource.setPublicId(publicId);
196
 
                iSource.setByteStream(is);
197
 
                return iSource;
198
 
            }
199
 
            catch (Exception e)
200
 
            {
201
 
                log.warn("Failed to create InputSource for " + resolved + " ("
202
 
                                + e.toString() + ")");
203
 
                return null;
204
 
            }
205
 
        }
206
 
 
207
 
        return null;
208
 
    }
209
 
 
210
 
    /**
211
 
     * Returns the logger used by this configuration object.
212
 
     *
213
 
     * @return the logger
214
 
     */
215
 
    public Log getLogger()
216
 
    {
217
 
        return log;
218
 
    }
219
 
 
220
 
    /**
221
 
     * Allows to set the logger to be used by this configuration object. This
222
 
     * method makes it possible for clients to exactly control logging behavior.
223
 
     * Per default a logger is set that will ignore all log messages. Derived
224
 
     * classes that want to enable logging should call this method during their
225
 
     * initialization with the logger to be used.
226
 
     *
227
 
     * @param log the new logger
228
 
     */
229
 
    public void setLogger(Log log)
230
 
    {
231
 
        this.log = (log != null) ? log : LogFactory.getLog(CatalogResolver.class);
232
 
    }
233
 
 
234
 
    private synchronized org.apache.xml.resolver.tools.CatalogResolver getResolver()
235
 
    {
236
 
        if (resolver == null)
237
 
        {
238
 
            resolver = new org.apache.xml.resolver.tools.CatalogResolver(manager);
239
 
        }
240
 
        return resolver;
241
 
    }
242
 
 
243
 
    /**
244
 
     * Extend the CatalogManager to make the FileSystem and base directory accessible.
245
 
     */
246
 
    public static class CatalogManager extends org.apache.xml.resolver.CatalogManager
247
 
    {
248
 
        /** The static catalog used by this manager. */
249
 
        private static org.apache.xml.resolver.Catalog staticCatalog;
250
 
 
251
 
        /** The FileSystem */
252
 
        private FileSystem fs;
253
 
 
254
 
        /** The base directory */
255
 
        private String baseDir = System.getProperty("user.dir");
256
 
 
257
 
        /** The String Substitutor */
258
 
        private StrSubstitutor substitutor;
259
 
 
260
 
        /**
261
 
         * Set the FileSystem
262
 
         * @param fileSystem The FileSystem in use.
263
 
         */
264
 
        public void setFileSystem(FileSystem fileSystem)
265
 
        {
266
 
            this.fs = fileSystem;
267
 
        }
268
 
 
269
 
        /**
270
 
         * Retrieve the FileSystem.
271
 
         * @return The FileSystem.
272
 
         */
273
 
        public FileSystem getFileSystem()
274
 
        {
275
 
            return this.fs;
276
 
        }
277
 
 
278
 
        /**
279
 
         * Set the base directory.
280
 
         * @param baseDir The base directory.
281
 
         */
282
 
        public void setBaseDir(String baseDir)
283
 
        {
284
 
            if (baseDir != null)
285
 
            {
286
 
                this.baseDir = baseDir;
287
 
            }
288
 
        }
289
 
 
290
 
        /**
291
 
         * Return the base directory.
292
 
         * @return The base directory.
293
 
         */
294
 
        public String getBaseDir()
295
 
        {
296
 
            return this.baseDir;
297
 
        }
298
 
 
299
 
        public void setSubstitutor(StrSubstitutor substitutor)
300
 
        {
301
 
            this.substitutor = substitutor;
302
 
        }
303
 
 
304
 
        public StrSubstitutor getStrSubstitutor()
305
 
        {
306
 
            return this.substitutor;
307
 
        }
308
 
 
309
 
 
310
 
        /**
311
 
         * Get a new catalog instance. This method is only overridden because xml-resolver
312
 
         * might be in a parent ClassLoader and will be incapable of loading our Catalog
313
 
         * implementation.
314
 
         *
315
 
         * This method always returns a new instance of the underlying catalog class.
316
 
         * @return the Catalog.
317
 
         */
318
 
        public org.apache.xml.resolver.Catalog getPrivateCatalog()
319
 
        {
320
 
            org.apache.xml.resolver.Catalog catalog = staticCatalog;
321
 
 
322
 
            if (catalog == null || !getUseStaticCatalog())
323
 
            {
324
 
                try
325
 
                {
326
 
                    catalog = new Catalog();
327
 
                    catalog.setCatalogManager(this);
328
 
                    catalog.setupReaders();
329
 
                    catalog.loadSystemCatalogs();
330
 
                }
331
 
                catch (Exception ex)
332
 
                {
333
 
                    ex.printStackTrace();
334
 
                }
335
 
 
336
 
                if (getUseStaticCatalog())
337
 
                {
338
 
                    staticCatalog = catalog;
339
 
                }
340
 
            }
341
 
 
342
 
            return catalog;
343
 
        }
344
 
 
345
 
        /**
346
 
         * Get a catalog instance.
347
 
         *
348
 
         * If this manager uses static catalogs, the same static catalog will
349
 
         * always be returned. Otherwise a new catalog will be returned.
350
 
         * @return The Catalog.
351
 
         */
352
 
        public org.apache.xml.resolver.Catalog getCatalog()
353
 
        {
354
 
            return getPrivateCatalog();
355
 
        }
356
 
    }
357
 
 
358
 
    /**
359
 
     * Overrides the Catalog implementation to use the underlying FileSystem.
360
 
     */
361
 
    public static class Catalog extends org.apache.xml.resolver.Catalog
362
 
    {
363
 
        /** The FileSystem */
364
 
        private FileSystem fs;
365
 
 
366
 
        /** FileNameMap to determine the mime type */
367
 
        private FileNameMap fileNameMap = URLConnection.getFileNameMap();
368
 
 
369
 
        /**
370
 
         * Load the catalogs.
371
 
         * @throws IOException if an error occurs.
372
 
         */
373
 
        public void loadSystemCatalogs() throws IOException
374
 
        {
375
 
            fs = ((CatalogManager) catalogManager).getFileSystem();
376
 
            String base = ((CatalogManager) catalogManager).getBaseDir();
377
 
 
378
 
            Vector catalogs = catalogManager.getCatalogFiles();
379
 
            if (catalogs != null)
380
 
            {
381
 
                for (int count = 0; count < catalogs.size(); count++)
382
 
                {
383
 
                    String fileName = (String) catalogs.elementAt(count);
384
 
 
385
 
                    URL url = null;
386
 
                    InputStream is = null;
387
 
 
388
 
                    try
389
 
                    {
390
 
                        url = ConfigurationUtils.locate(fs, base, fileName);
391
 
                        if (url != null)
392
 
                        {
393
 
                            is = fs.getInputStream(url);
394
 
                        }
395
 
                    }
396
 
                    catch (ConfigurationException ce)
397
 
                    {
398
 
                        String name = (url == null) ? fileName : url.toString();
399
 
                        // Ignore the exception.
400
 
                        catalogManager.debug.message(DEBUG_ALL,
401
 
                            "Unable to get input stream for " + name + ". " + ce.getMessage());
402
 
                    }
403
 
                    if (is != null)
404
 
                    {
405
 
                        String mimeType = fileNameMap.getContentTypeFor(fileName);
406
 
                        try
407
 
                        {
408
 
                            if (mimeType != null)
409
 
                            {
410
 
                                parseCatalog(mimeType, is);
411
 
                                continue;
412
 
                            }
413
 
                        }
414
 
                        catch (Exception ex)
415
 
                        {
416
 
                            // Ignore the exception.
417
 
                            catalogManager.debug.message(DEBUG_ALL,
418
 
                                "Exception caught parsing input stream for " + fileName + ". "
419
 
                                + ex.getMessage());
420
 
                        }
421
 
                        finally
422
 
                        {
423
 
                            is.close();
424
 
                        }
425
 
                    }
426
 
                    parseCatalog(base, fileName);
427
 
                }
428
 
            }
429
 
 
430
 
        }
431
 
 
432
 
        /**
433
 
         * Parse the specified catalog file.
434
 
         * @param baseDir The base directory, if not included in the file name.
435
 
         * @param fileName The catalog file. May be a full URI String.
436
 
         * @throws IOException If an error occurs.
437
 
         */
438
 
        public void parseCatalog(String baseDir, String fileName) throws IOException
439
 
        {
440
 
            base = ConfigurationUtils.locate(fs, baseDir, fileName);
441
 
            catalogCwd = base;
442
 
            default_override = catalogManager.getPreferPublic();
443
 
            catalogManager.debug.message(DEBUG_NORMAL, "Parse catalog: " + fileName);
444
 
 
445
 
            boolean parsed = false;
446
 
 
447
 
            for (int count = 0; !parsed && count < readerArr.size(); count++)
448
 
            {
449
 
                CatalogReader reader = (CatalogReader) readerArr.get(count);
450
 
                InputStream inStream;
451
 
 
452
 
                try
453
 
                {
454
 
                    inStream = fs.getInputStream(base);
455
 
                }
456
 
                catch (Exception ex)
457
 
                {
458
 
                    catalogManager.debug.message(DEBUG_NORMAL, "Unable to access " + base
459
 
                        + ex.getMessage());
460
 
                    break;
461
 
                }
462
 
 
463
 
                try
464
 
                {
465
 
                    reader.readCatalog(this, inStream);
466
 
                    parsed = true;
467
 
                }
468
 
                catch (CatalogException ce)
469
 
                {
470
 
                    catalogManager.debug.message(DEBUG_NORMAL, "Parse failed for " + fileName
471
 
                            + ce.getMessage());
472
 
                    if (ce.getExceptionType() == CatalogException.PARSE_FAILED)
473
 
                    {
474
 
                        break;
475
 
                    }
476
 
                    else
477
 
                    {
478
 
                        // try again!
479
 
                        continue;
480
 
                    }
481
 
                }
482
 
                finally
483
 
                {
484
 
                    try
485
 
                    {
486
 
                        inStream.close();
487
 
                    }
488
 
                    catch (IOException ioe)
489
 
                    {
490
 
                        // Ignore the exception.
491
 
                        inStream = null;
492
 
                    }
493
 
                }
494
 
            }
495
 
 
496
 
            if (parsed)
497
 
            {
498
 
                parsePendingCatalogs();
499
 
            }
500
 
        }
501
 
 
502
 
        /**
503
 
         * Perform character normalization on a URI reference.
504
 
         *
505
 
         * @param uriref The URI reference
506
 
         * @return The normalized URI reference.
507
 
         */
508
 
        protected String normalizeURI(String uriref)
509
 
        {
510
 
            StrSubstitutor substitutor = ((CatalogManager) catalogManager).getStrSubstitutor();
511
 
            String resolved = substitutor != null ? substitutor.replace(uriref) : uriref;
512
 
            return super.normalizeURI(resolved);
513
 
        }
514
 
    }
515
 
}