001    /*
002    // $Id: //open/mondrian/src/main/mondrian/spi/impl/FilterDynamicSchemaProcessor.java#1 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2007-2007 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.spi.impl;
011    
012    import mondrian.spi.DynamicSchemaProcessor;
013    import mondrian.olap.Util;
014    import org.apache.commons.vfs.FileSystemManager;
015    import org.apache.commons.vfs.VFS;
016    import org.apache.commons.vfs.FileObject;
017    import org.apache.commons.vfs.FileContent;
018    
019    import java.io.File;
020    import java.io.InputStream;
021    import java.io.BufferedReader;
022    import java.io.InputStreamReader;
023    
024    /**
025     * Implementation of {@link DynamicSchemaProcessor} which allows a derived class
026     * to easily process a schema file.
027     *
028     * <p>Mondrian's default mechanism for loading schema files, if no
029     * DynamicSchemaProcessor is specified, is to use Apache VFS (virtual file
030     * system) to resolve the URL to a stream, and to read the contents of the
031     * stream into a string.
032     *
033     * <p>FilterDynamicSchemaProcessor implements exactly the
034     * same mechanism, but makes it easy for a derived class to override the
035     * mechanism. For example:<ul>
036     *
037     * <li>To redirect to a different URL, override the
038     * {@link #processSchema(String, mondrian.olap.Util.PropertyList)} method.
039     *
040     * <li>To process the contents of the URL, override the
041     * {@link #filter(String, mondrian.olap.Util.PropertyList, java.io.InputStream)}
042     * method.
043     *
044     * </ul>
045     *
046     * @author jhyde
047     * @version $Id: //open/mondrian/src/main/mondrian/spi/impl/FilterDynamicSchemaProcessor.java#1 $
048     * @since Mar 30, 2007
049     */
050    public class FilterDynamicSchemaProcessor implements DynamicSchemaProcessor {
051    
052        /**
053         * {@inheritDoc}
054         *
055         * <p>FilterDynamicSchemaProcessor's implementation of this method reads
056         * from the URL supplied (that is, it does not perform URL translation)
057         * and passes it through the {@link #filter} method.
058         */
059        public String processSchema(
060            String schemaUrl,
061            Util.PropertyList connectInfo) throws Exception
062        {
063            FileSystemManager fsManager = VFS.getManager();
064            File userDir = new File("").getAbsoluteFile();
065            FileObject file = fsManager.resolveFile(userDir, schemaUrl);
066            FileContent fileContent = file.getContent();
067            return filter(schemaUrl, connectInfo, fileContent.getInputStream());
068        }
069    
070        /**
071         * Reads the contents of a schema as a stream and returns the result as
072         * a string.
073         *
074         * <p>The default implementation returns the contents of the schema
075         * unchanged.
076         *
077         * @param schemaUrl the URL of the catalog
078         * @param connectInfo Connection properties
079         * @param stream Schema contents represented as a stream
080         * @return the modified schema
081         * @throws Exception if an error occurs
082         */
083        protected String filter(
084            String schemaUrl,
085            Util.PropertyList connectInfo,
086            InputStream stream)
087            throws Exception
088        {
089            BufferedReader in =
090                new BufferedReader(
091                    new InputStreamReader(stream));
092            try {
093                StringBuilder builder = new StringBuilder();
094                char[] buf = new char[2048];
095                int readCount;
096                while ((readCount = in.read(buf, 0, buf.length)) >= 0) {
097                    builder.append(buf, 0, readCount);
098                }
099                return builder.toString();
100            } finally {
101                in.close();
102            }
103        }
104    }
105    
106    // End FilterDynamicSchemaProcessor.java