Package mondrian.xmla.impl

Source Code of mondrian.xmla.impl.DynamicDatasourceXmlaServlet

/*
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2006-2009 Julian Hyde
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/

package mondrian.xmla.impl;

import mondrian.olap.Util;
import mondrian.rolap.CacheControlImpl;
import mondrian.rolap.RolapSchema;
import mondrian.xmla.DataSourcesConfig;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* Extends DefaultXmlaServlet to add dynamic datasource loading capability.
* Limitations : Catalog name should be unique across the datasources
*
* @author Thiyagu, Ajit
*/
public class DynamicDatasourceXmlaServlet extends DefaultXmlaServlet {
    protected URL dataSourcesConfigUrl;
    protected String lastDataSourcesConfigString;

    protected void doPost(
        HttpServletRequest request,
        HttpServletResponse response)
        throws ServletException, IOException
    {
        reloadDataSources();
        super.doPost(request, response);
    }

    /**
     * Checks for updates to datasources content, flushes obsolete catalogs
     */
    void reloadDataSources() {
        try {
            String dataSourcesConfigString =
                readDataSourcesContent(dataSourcesConfigUrl);
            if (hasDataSourcesContentChanged(dataSourcesConfigString)) {
                DataSourcesConfig.DataSources newDataSources =
                        parseDataSources(dataSourcesConfigString);
                if (newDataSources != null) {
                    flushObsoleteCatalogs(newDataSources);
                    this.dataSources = newDataSources;
                    xmlaHandler = null;
                    lastDataSourcesConfigString = dataSourcesConfigString;
                }
            }
        } catch (Exception e) {
            throw Util.newError(
                e,
                "Failed to parse data sources config '"
                + dataSourcesConfigUrl.toExternalForm() + "'");
        }
    }

    protected boolean hasDataSourcesContentChanged(
        String dataSourcesConfigString)
    {
        return dataSourcesConfigString != null
            && !dataSourcesConfigString.equals(
                this.lastDataSourcesConfigString);
    }

    /**
     * Overides XmlaServlet.parseDataSourcesUrl to store dataSorucesConfigUrl,
     * Datasoruces Configuration content.
     *
     * @param dataSourcesConfigUrl
     */
    protected DataSourcesConfig.DataSources parseDataSourcesUrl(
        URL dataSourcesConfigUrl)
    {
        this.dataSourcesConfigUrl = dataSourcesConfigUrl;
        try {
            String dataSourcesConfigString =
                readDataSourcesContent(dataSourcesConfigUrl);
            if (lastDataSourcesConfigString == null) {
                // This is the first time we are reading any datasource config
                this.lastDataSourcesConfigString = dataSourcesConfigString;
            }
            return parseDataSources(dataSourcesConfigString);
        } catch (Exception e) {
            throw Util.newError(
                e,
                "Failed to parse data sources config '"
                + dataSourcesConfigUrl.toExternalForm() + "'");
        }
    }

    void flushObsoleteCatalogs(DataSourcesConfig.DataSources newDataSources) {
        Map<String, DataSourcesConfig.Catalog> newDatasourceCatalogs =
            createCatalogMap(newDataSources);

        for (DataSourcesConfig.DataSource oldDataSource
            : dataSources.dataSources)
        {
            for (DataSourcesConfig.Catalog oldCatalog
                : oldDataSource.catalogs.catalogs)
            {
                DataSourcesConfig.Catalog newCatalog =
                        newDatasourceCatalogs.get(oldCatalog.name);
                if (!(newCatalog != null
                      && areCatalogsEqual(oldCatalog, newCatalog)))
                {
                    flushCatalog(oldCatalog.name);
                }
            }
        }
    }

    private Map<String, DataSourcesConfig.Catalog> createCatalogMap(
        DataSourcesConfig.DataSources newDataSources)
    {
        Map<String, DataSourcesConfig.Catalog> newDatasourceCatalogNames =
                new HashMap<String, DataSourcesConfig.Catalog>();
        for (DataSourcesConfig.DataSource dataSource
            : newDataSources.dataSources)
        {
            for (DataSourcesConfig.Catalog catalog
                : dataSource.catalogs.catalogs)
            {
                newDatasourceCatalogNames.put(catalog.name, catalog);
            }
        }
        return newDatasourceCatalogNames;
    }

    void flushCatalog(String catalogName) {
        Iterator schemas = RolapSchema.getRolapSchemas();
        while (schemas.hasNext()) {
            RolapSchema curSchema = (RolapSchema) schemas.next();
            if (curSchema.getName().equals(catalogName)) {
                new CacheControlImpl().flushSchema(curSchema);
            }
        }
    }

    boolean areCatalogsEqual(
        DataSourcesConfig.Catalog catalog1,
        DataSourcesConfig.Catalog catalog2)
    {
        if ((catalog1.getDataSourceInfo() != null
             && catalog2.getDataSourceInfo() == null)
            || (catalog2.getDataSourceInfo() != null
                && catalog1.getDataSourceInfo() == null))
        {
            return false;
        }

        if ((catalog1.getDataSourceInfo() == null
             && catalog2.getDataSourceInfo() == null)
            || (catalog1.getDataSourceInfo().equals(
                catalog2.getDataSourceInfo())))
        {
            return catalog1.name.equals(catalog2.name)
                && catalog1.definition.equals(catalog2.definition);
        }
        return false;
    }
}

// End DynamicDatasourceXmlaServlet.java
TOP

Related Classes of mondrian.xmla.impl.DynamicDatasourceXmlaServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.