001    package fi.iki.hsivonen.xml;
002    
003    import java.io.File;
004    import java.io.FileInputStream;
005    import java.io.IOException;
006    import java.util.Map;
007    
008    import org.xml.sax.EntityResolver;
009    import org.xml.sax.InputSource;
010    import org.xml.sax.SAXException;
011    
012    /**
013     * @version $Id: LocalCacheEntityResolver.java,v 1.4 2006/11/14 22:32:44 hsivonen Exp $
014     * @author hsivonen
015     */
016    public class LocalCacheEntityResolver implements EntityResolver {
017    
018        private Map pathMap;
019    
020        private EntityResolver delegate;
021        
022        private boolean allowRnc = false;
023    
024        /**
025         * @param pathMap
026         * @param delegate
027         */
028        public LocalCacheEntityResolver(Map pathMap, EntityResolver delegate) {
029            this.pathMap = pathMap;
030            this.delegate = delegate;
031        }
032        /**
033         * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String,
034         *      java.lang.String)
035         */
036        public InputSource resolveEntity(String publicId, String systemId)
037                throws SAXException, IOException {
038            String path;
039            synchronized(pathMap) {
040                path = (String) pathMap.get(systemId);
041            }
042            if(path != null) {
043                File f = new File(path);
044                if (f.exists()) {
045                    TypedInputSource is = new TypedInputSource();
046                    is.setByteStream(new FileInputStream(f));
047                    is.setSystemId(systemId);
048                    is.setPublicId(publicId);
049                    if(systemId.endsWith(".rnc")) {
050                        is.setType("application/relax-ng-compact-syntax");
051                        if(!allowRnc) {
052                            throw new IOException("Not an XML resource: " + systemId);
053                        }
054                    } else if(systemId.endsWith(".dtd")) {
055                        is.setType("application/xml-dtd");  
056                    } else if(systemId.endsWith(".ent")) {
057                        is.setType("application/xml-external-parsed-entity");                    
058                    } else {
059                        is.setType("application/xml");                    
060                    }
061                    return is;
062                }            
063            }
064            return delegate.resolveEntity(publicId, systemId);
065        }
066    
067        /**
068         * @return Returns the allowRnc.
069         */
070        public boolean isAllowRnc() {
071            return allowRnc;
072        }
073        /**
074         * @param allowRnc The allowRnc to set.
075         */
076        public void setAllowRnc(boolean allowRnc) {
077            this.allowRnc = allowRnc;
078        }
079    }