Package org.pentaho.platform.plugin.action.mondrian.catalog

Source Code of org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalogHelper

/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation..  All rights reserved.
*/

package org.pentaho.platform.plugin.action.mondrian.catalog;

import mondrian.i18n.LocalizingDynamicSchemaProcessor;
import mondrian.olap.MondrianDef;
import mondrian.olap.Util;
import mondrian.olap.Util.PropertyList;
import mondrian.rolap.RolapConnectionProperties;
import mondrian.rolap.agg.AggregationManager;
import mondrian.spi.DynamicSchemaProcessor;
import mondrian.util.ClassResolver;
import mondrian.xmla.DataSourcesConfig;
import mondrian.xmla.DataSourcesConfig.DataSources;

import org.apache.commons.collections.list.SetUniqueList;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.VFS;
import org.apache.commons.vfs.impl.DefaultFileSystemManager;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.eigenbase.xom.DOMWrapper;
import org.eigenbase.xom.Parser;
import org.eigenbase.xom.XMLOutput;
import org.eigenbase.xom.XOMException;
import org.eigenbase.xom.XOMUtil;
import org.owasp.esapi.ESAPI;
import org.owasp.esapi.Encoder;
import org.pentaho.platform.api.data.DBDatasourceServiceException;
import org.pentaho.platform.api.data.IDBDatasourceService;
import org.pentaho.platform.api.engine.ICacheManager;
import org.pentaho.platform.api.engine.IPentahoSession;
import org.pentaho.platform.api.engine.ObjectFactoryException;
import org.pentaho.platform.api.repository2.unified.IUnifiedRepository;
import org.pentaho.platform.api.repository2.unified.RepositoryFile;
import org.pentaho.platform.api.repository2.unified.data.node.DataNode;
import org.pentaho.platform.api.repository2.unified.data.node.NodeRepositoryFileData;
import org.pentaho.platform.api.util.XmlParseException;
import org.pentaho.platform.engine.core.system.PentahoRequestContextHolder;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.pentaho.platform.engine.services.solution.PentahoEntityResolver;
import org.pentaho.platform.plugin.action.messages.Messages;
import org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalogServiceException.Reason;
import org.pentaho.platform.repository.solution.filebased.MondrianVfs;
import org.pentaho.platform.repository.solution.filebased.SolutionRepositoryVfsFileObject;
import org.pentaho.platform.repository2.ClientRepositoryPaths;
import org.pentaho.platform.util.logging.Logger;
import org.pentaho.platform.util.messages.LocaleHelper;
import org.pentaho.platform.util.xml.dom4j.XmlDom4JHelper;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXParseException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

/**
* Reads in file containing Mondrian data sources and catalogs. (Contains code copied from <code>XmlaServlet</code>.)
*
*
* @author mlowery
*/
public class MondrianCatalogHelper implements IMondrianCatalogService {

  // ~ Static fields/initializers ======================================================================================

  private static final Log logger = LogFactory.getLog( MondrianCatalogHelper.class );

  // ~ Instance fields =================================================================================================

  private String dataSourcesConfig;

  /**
   * true to use schema name from catalog definition (aka schema file) as catalog name.
   */
  private boolean useSchemaNameAsCatalogName = true;

  /**
   * Holds the additional catalog information
   */
  private Map<String, MondrianCatalogComplementInfo> catalogComplementInfoMap;

  public static final String MONDRIAN_DATASOURCE_FOLDER = "mondrian"; //$NON-NLS-1$

  // ~ Constructors ====================================================================================================

  @SuppressWarnings ( "unchecked" )
  private List<MondrianCatalog> getCatalogs( IPentahoSession pentahoSession ) {

    Map<String, MondrianCatalog> catalogsMap =
      (Map<String, MondrianCatalog>) PentahoSystem.getCacheManager( pentahoSession ).getFromRegionCache(
        MONDRIAN_CATALOG_CACHE_REGION, getLocale().toString() );

    List<MondrianCatalog> catalogs = new ArrayList<MondrianCatalog>();
    // Analyzer cache is also placed in the MONDRIAN_CATALOG_CACHE_REGION
    // so we need to filter the list to only keep MondrianCatalog objects
    for ( Object o : catalogsMap.values() ) {
      if ( o instanceof MondrianCatalog ) {
        catalogs.add( (MondrianCatalog) o );
      }
    }
    // Sort
    Collections.sort( catalogs, new Comparator<MondrianCatalog>() {
      public int compare( MondrianCatalog o1, MondrianCatalog o2 ) {
        return o1.getName().compareTo( o2.getName() );
      }
    } );
    // remove duplicates
    SetUniqueList uniqueCatalogs = SetUniqueList.decorate( catalogs );
    return uniqueCatalogs;
  }

  /**
   * Performs a search for an existing catalog based on the datasource info and catalog definition.
   *
   * @param catalog        The catalog to compare against
   * @param pentahoSession The session with which this request is associated (Used to locate the cache)
   * @return True if an existing match has been found for the catalog
   */
  private boolean catalogExists( MondrianCatalog catalog, IPentahoSession pentahoSession ) {
    if ( catalog != null ) {
      MondrianCatalog foundCatalog = getCatalogFromCache( catalog.getName(), pentahoSession );
      // Was the catalog found by name?
      if ( foundCatalog != null ) {
        // first check dataSourceInfo
        String foundDataSourceInfo = cleanseDataSourceInfo( foundCatalog.getDataSourceInfo() );
        String newDataSourceInfo = cleanseDataSourceInfo( catalog.getDataSourceInfo() );

        if ( !foundDataSourceInfo.equals( newDataSourceInfo ) ) {
          return false;
        }

        // now check definition
        String foundDefinition = foundCatalog.getDefinition();
        String newDefinition = catalog.getDefinition();

        if ( definitionEquals( foundDefinition, newDefinition ) ) {
          return true;
        }
      }
    }
    return false;
  }

  private static final MondrianCatalog getCatalogFromCache( String context, IPentahoSession pentahoSession ) {
    // NOTE that the context can be the catalog name or the definition string for the catalog. If you are using the
    // definition string to
    // retrieve the catalog form the cache, you cannot be guaranteed what datasource is in play; so under these
    // circumstances, this catalog's
    // definition is the only part of the catalog that can be trusted. As this feature was added to enable looking up
    // Mondrian
    // roles from the schema, we don't much care which datasource is in play.
    Map<String, MondrianCatalog> catalogs =
      (Map<String, MondrianCatalog>) PentahoSystem.getCacheManager( pentahoSession ).getFromRegionCache(
        MONDRIAN_CATALOG_CACHE_REGION, getLocale().toString() );
    return catalogs.get( context );
  }

  /**
   * TODO Delete this method. Calling this method ties you to this implementation.
   *
   * @deprecated Please use PentahoSystem.get to get the Mondrian Catalog Service
   */
  public static MondrianCatalogHelper getInstance() {
    // IMondrianCatalogService is a singleton; IPentahoSession not required
    return (MondrianCatalogHelper) PentahoSystem
      .get( IMondrianCatalogService.class, "IMondrianCatalogService", null ); //$NON-NLS-1$
  }

  public MondrianCatalogHelper() {
    super();

    try {
      DefaultFileSystemManager dfsm = (DefaultFileSystemManager) VFS.getManager();
      dfsm.addProvider( "mondrian", new MondrianVfs() ); //$NON-NLS-1$
    } catch ( FileSystemException e ) {
      logger.error( e.getMessage() );
    }
  }

  public static String MONDRIAN_CATALOG_CACHE_REGION = "mondrian-catalog-cache"; //$NON-NLS-1$

  // ~ Methods =========================================================================================================

  protected synchronized void init( final IPentahoSession pentahoSession ) {
    // First check if the catalogs are initialized for the current locale
    final ICacheManager cacheMgr = PentahoSystem.getCacheManager( pentahoSession );
    if ( cacheMgr.cacheEnabled( MONDRIAN_CATALOG_CACHE_REGION )
      && cacheMgr.getFromRegionCache( MONDRIAN_CATALOG_CACHE_REGION, getLocale().toString() ) != null ) {
      return;
    }
    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger.debug( "init" ); //$NON-NLS-1$
    }
    // By default, we will use the system to load all schemas into the cache.
    // access to these schemas is controlled later via the hasAccess() method
    loadCatalogsIntoCache( makeDataSources(), PentahoSessionHolder.getSession() );
    AggregationManager.instance().getCacheControl( null, null ).flushSchemaCache();
  }

  public synchronized void reInit( final IPentahoSession pentahoSession ) {
    final ICacheManager cacheMgr = PentahoSystem.getCacheManager( pentahoSession );
    if ( cacheMgr.cacheEnabled( MONDRIAN_CATALOG_CACHE_REGION ) ) {
      cacheMgr.clearRegionCache( MONDRIAN_CATALOG_CACHE_REGION );
    }
    init( pentahoSession );
  }

  private static Locale getLocale() {
    final Locale locale = LocaleHelper.getLocale();
    if ( locale != null ) {
      return locale;
    } else {
      return Locale.getDefault();
    }
  }

  /**
   * Same as implemented in <code>XmlaServlet</code> except takes advantage of Spring's Resource framework.
   */
  protected DataSourcesConfig.DataSources makeDataSources() {
    try {
      URL dataSourcesConfigUrl = null;

      if ( dataSourcesConfig == null ) {
        String datasourcesXML =
          generateInMemoryDatasourcesXml( PentahoSystem.get( IUnifiedRepository.class, PentahoSessionHolder
            .getSession() ) );
        return parseDataSources( datasourcesXML );
      } else if ( dataSourcesConfig.startsWith( "file:" ) ) { //$NON-NLS-1$
        dataSourcesConfigUrl = new URL( dataSourcesConfig ); // dataSourcesConfigResource.getURL();
        return ( dataSourcesConfigUrl == null ) ? null : parseDataSourcesUrl( dataSourcesConfigUrl );
      } else if ( dataSourcesConfig.startsWith( "classpath:" ) ) { //$NON-NLS-1$
        dataSourcesConfigUrl = getClass().getResource( dataSourcesConfig.substring( 10 ) );
        return ( dataSourcesConfigUrl == null ) ? null : parseDataSourcesUrl( dataSourcesConfigUrl );
      } else {
        throw new MondrianCatalogServiceException( "dataSourcesConfig is not a valid URL or does not exist",
          //$NON-NLS-1$
          Reason.GENERAL );
      }
    } catch ( IOException e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0001_INVALID_DATASOURCE_CONFIG", dataSourcesConfig ), //$NON-NLS-1$
        e, Reason.GENERAL );
    }
  }

  public String generateInMemoryDatasourcesXml( IUnifiedRepository unifiedRepository ) {

    StringBuffer datasourcesXML = new StringBuffer();
    datasourcesXML.append( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<DataSources>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<DataSource>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<DataSourceName>Pentaho</DataSourceName>\n" ); //$NON-NLS-1$
    datasourcesXML
      .append( "<DataSourceDescription>Pentaho BI Platform Datasources</DataSourceDescription>\n" ); //$NON-NLS-1$
    datasourcesXML.append(
      "<URL>" + PentahoRequestContextHolder.getRequestContext().getContextPath() + "Xmla</URL>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<DataSourceInfo>Provider=mondrian</DataSourceInfo>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<ProviderName>PentahoXMLA</ProviderName>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<ProviderType>MDP</ProviderType>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<AuthenticationMode>Unauthenticated</AuthenticationMode>\n" ); //$NON-NLS-1$
    datasourcesXML.append( "<Catalogs>\n" ); //$NON-NLS-1$

    Encoder encoder = ESAPI.encoder();

    // Creates <Catalogs> from the "/etc/mondrian/<catalog>/metadata" nodes.
    /*
     * IPentahoSession pentahoSession = PentahoSessionHolder.getSession(); String tenantEtcFolder = null;
     * if(pentahoSession != null) { String tenantId = (String)
     * pentahoSession.getAttribute(IPentahoSession.TENANT_ID_KEY); tenantEtcFolder =
     * ServerRepositoryPaths.getTenantEtcFolderPath(tenantId); } else { tenantEtcFolder =
     * ServerRepositoryPaths.getTenantEtcFolderPath(); }
     */

    String etcMondrian =
      ClientRepositoryPaths.getEtcFolderPath() + RepositoryFile.SEPARATOR + MONDRIAN_DATASOURCE_FOLDER;

    RepositoryFile etcMondrianFolder = unifiedRepository.getFile( etcMondrian );
    if ( etcMondrianFolder != null ) {
      List<RepositoryFile> mondrianCatalogs = unifiedRepository.getChildren( etcMondrianFolder.getId() );

      for ( RepositoryFile catalog : mondrianCatalogs ) {

        String catalogName = catalog.getName();
        RepositoryFile metadata =
          unifiedRepository.getFile( etcMondrian + RepositoryFile.SEPARATOR + catalogName + RepositoryFile.SEPARATOR
            + "metadata" ); //$NON-NLS-1$

        if ( metadata != null ) {
          DataNode metadataNode =
            unifiedRepository.getDataForRead( metadata.getId(), NodeRepositoryFileData.class ).getNode();
          String datasourceInfo = metadataNode.getProperty( "datasourceInfo" ).getString(); //$NON-NLS-1$
          String definition = metadataNode.getProperty( "definition" ).getString(); //$NON-NLS-1$

          datasourcesXML.append( "<Catalog name=\"" + encoder.encodeForXML( catalogName ) + "\">\n" ); //$NON-NLS-1$ //$NON-NLS-2$
          datasourcesXML
            .append( "<DataSourceInfo>" + encoder.encodeForXML( datasourceInfo ) + "</DataSourceInfo>\n" ); //$NON-NLS-1$ //$NON-NLS-2$
          datasourcesXML.append( "<Definition>" + encoder.encodeForXML( definition ) + "</Definition>\n" ); //$NON-NLS-1$ //$NON-NLS-2$
          datasourcesXML.append( "</Catalog>\n" ); //$NON-NLS-1$
        } else {
          logger
            .warn( Messages.getInstance().getString( "MondrianCatalogHelper.WARN_META_DATA_IS_NULL" ) ); //$NON-NLS-1$
        }
      }

      datasourcesXML.append( "</Catalogs>\n" ); //$NON-NLS-1$
      datasourcesXML.append( "</DataSource>\n" ); //$NON-NLS-1$
      datasourcesXML.append( "</DataSources>\n" ); //$NON-NLS-1$
      return datasourcesXML.toString();
    } else {
      return null;
    }
  }

  protected DataSourcesConfig.DataSources parseDataSourcesUrl( final URL dataSourcesConfigUrl ) {

    try {
      String dataSourcesConfigString = readDataSourcesContent( dataSourcesConfigUrl );
      return parseDataSources( dataSourcesConfigString );

    } catch ( Exception e ) {
      throw Util
        .newError(
          e,
          Messages
            .getInstance()
            .getErrorString(
              "MondrianCatalogHelper.ERROR_0002_FAILED_TO_PARSE_DATASOURCE_CONFIG",
              dataSourcesConfigUrl.toExternalForm() ) );
    }
  }

  protected String readDataSourcesContent( final URL dataSourcesConfigUrl ) throws IOException {
    return Util.readURL( dataSourcesConfigUrl, Util.toMap( System.getProperties() ) );
  }

  protected DataSourcesConfig.DataSources parseDataSources( final String dataSourcesConfigString ) {

    try {
      if ( dataSourcesConfigString == null ) {
        MondrianCatalogHelper.logger.warn( Messages.getInstance().getString(
          "MondrianCatalogHelper.WARN_PARSE_NULL_INPUT" ) ); //$NON-NLS-1$
        return null;
      }
      String replacedConfigString =
        Util.replaceProperties( dataSourcesConfigString, Util.toMap( System.getProperties() ) );

      if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
        String msg = "parseDataSources: dataSources=" + replacedConfigString; //$NON-NLS-1$
        MondrianCatalogHelper.logger.debug( msg );
      }
      final Parser parser = XOMUtil.createDefaultParser();
      final DOMWrapper doc = parser.parse( replacedConfigString );
      catalogComplementInfoMap = makeCatalogComplementInfoMap( doc );
      return new DataSourcesConfig.DataSources( doc );

    } catch ( XOMException e ) {
      throw Util.newError( e, Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0002_FAILED_TO_PARSE_DATASOURCE_CONFIG", dataSourcesConfigString ) ); //$NON-NLS-1$
    }
  }

  protected Map<String, MondrianCatalogComplementInfo> makeCatalogComplementInfoMap( final DOMWrapper doc ) {

    HashMap<String, MondrianCatalogComplementInfo> map = new HashMap<String, MondrianCatalogComplementInfo>();

    if ( doc.getElementChildren().length > 0 ) {

      DOMWrapper dataSource = doc.getElementChildren()[ 0 ];
      DOMWrapper catalogs = null;

      // Search Catalogs
      for ( int i = 0; i < dataSource.getElementChildren().length; i++ ) {
        DOMWrapper element = dataSource.getElementChildren()[ i ];
        if ( element.getTagName().equals( "Catalogs" ) ) { //$NON-NLS-1$
          catalogs = element;
          break;
        }
      }

      // Generate the map. We need the name and the variables
      for ( int i = 0; i < catalogs.getElementChildren().length; i++ ) {
        final DOMWrapper catalog = catalogs.getElementChildren()[ i ];
        if ( !"Catalog".equals( catalog.getTagName() ) ) { //$NON-NLS-1$
          continue;
        }

        MondrianCatalogComplementInfo complementInfo = new MondrianCatalogComplementInfo();

        // Iterate through whereConditions
        for ( int j = 0; j < catalog.getElementChildren().length; j++ ) {
          final DOMWrapper whereNode = catalog.getElementChildren()[ j ];
          if ( "WhereCondition".equals( whereNode.getTagName() ) ) { //$NON-NLS-1$
            complementInfo.addWhereCondition( whereNode.getAttribute( "cube" ), whereNode.getText() ); //$NON-NLS-1$
          }
        }

        map.put( getDOMWrapperElementText( catalog, "Definition" ), complementInfo ); //$NON-NLS-1$
      }

    }

    return map;
  }

  private String getDOMWrapperElementText( final DOMWrapper element, final String name ) {

    for ( int i = 0; i < element.getElementChildren().length; i++ ) {
      DOMWrapper child = element.getElementChildren()[ i ];
      if ( child.getTagName().equals( name ) ) {
        return child.getText();
      }
    }

    return null;
  }

  protected Map<String, MondrianCatalog> makeCatalogMap( final List<MondrianCatalog> cats ) {
    Map<String, MondrianCatalog> map = new HashMap<String, MondrianCatalog>();
    for ( MondrianCatalog catalog : cats ) {
      map.put( catalog.getName(), catalog );
    }
    return map;
  }

  /**
   * Equals that is tolerant of inconsistencies in solution path (leading slash vs. no leading slash).
   */
  private boolean definitionEquals( final String def1, final String def2 ) {
    if ( def1.equals( def2 ) ) {
      return true;
    }
    String tmp =
      def1.startsWith( "solution:/" ) ? "solution:" + def1.substring( 10 )
        : "solution:/" + def1.substring( 9 ); //$NON-NLS-1$
    return tmp.equals( def2 );
  }

  protected String cleanseDataSourceInfo( String dataSourceInfo ) {
    if ( dataSourceInfo == null ) {
      return null;
    }
    // remove EnableXmla if necessary before building the key
    PropertyList propertyList = Util.parseConnectString( dataSourceInfo );
    if ( propertyList.get( "EnableXmla" ) != null ) { //$NON-NLS-1$
      propertyList.remove( "EnableXmla" ); //$NON-NLS-1$
    }
    if ( propertyList.get( "overwrite" ) != null ) { //$NON-NLS-1$
      propertyList.remove( "overwrite" ); //$NON-NLS-1$
    }
    return propertyList.toString();
  }

  public String getDataSourcesConfig() {
    return dataSourcesConfig;
  }

  public void setDataSourcesConfig( final String dataSourcesConfig ) {
    this.dataSourcesConfig = dataSourcesConfig;
  }

  public List<MondrianCatalog> listCatalogs( final IPentahoSession pentahoSession, final boolean jndiOnly ) {
    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger.debug( "listCatalogs" ); //$NON-NLS-1$
    }
    init( pentahoSession );

    // defensive copy
    return Collections.unmodifiableList( filter( getCatalogs( pentahoSession ), pentahoSession, jndiOnly ) );
  }

  /**
   * use the in memory session value of input stream (used by test harness)
   */
  public synchronized void addCatalog( final MondrianCatalog catalog, final boolean overwrite,
                                       final IPentahoSession pentahoSession ) throws MondrianCatalogServiceException {
    String mondrianSchema = (String) pentahoSession.getAttribute( "MONDRIAN_SCHEMA_XML_CONTENT" ); //$NON-NLS-1$
    InputStream schemaInputStream = IOUtils.toInputStream( mondrianSchema );
    addCatalog( schemaInputStream, catalog, overwrite, pentahoSession );
  }

  /**
   * new method to pass the input stream directly from data access put and post schema
   *
   * @param schemaInputStream
   * @param catalog
   * @param overwrite
   * @param pentahoSession
   * @throws MondrianCatalogServiceException
   *
   */
  public synchronized void addCatalog( InputStream schemaInputStream, final MondrianCatalog catalog,
                                       final boolean overwrite, final IPentahoSession pentahoSession )
    throws MondrianCatalogServiceException {
    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger.debug( "addCatalog" ); //$NON-NLS-1$
    }

    init( pentahoSession );

    // do an access check first
    if ( !hasAccess( catalog, CatalogPermission.WRITE, pentahoSession ) ) {
      if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
        MondrianCatalogHelper.logger.debug( "user does not have access; throwing exception" ); //$NON-NLS-1$
      }
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0003_INSUFFICIENT_PERMISSION" ), Reason.ACCESS_DENIED ); //$NON-NLS-1$
    }

    // check for existing dataSourceInfo+catalog
    if ( catalogExists( catalog, pentahoSession ) && !overwrite ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0004_ALREADY_EXISTS" ), Reason.ALREADY_EXISTS ); //$NON-NLS-1$
    }

    // Checks if a catalog of the same name but with a different file
    // path exists.
    MondrianCatalog fileLocationCatalogTest = null;
    for ( MondrianCatalog currentCatalogCheck : getCatalogs( pentahoSession ) ) {
      if ( currentCatalogCheck.getName().equals( catalog.getName() ) ) {
        fileLocationCatalogTest = currentCatalogCheck;
        break;
      }
    }
    //compare the catalog names and throw exception if same and NOT ovewrite
    if ( fileLocationCatalogTest != null
      && definitionEquals( fileLocationCatalogTest.getDefinition(),
        "mondrian:/" + catalog.getName() )
        && !overwrite ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0004_ALREADY_EXISTS" ), //$NON-NLS-1$
        Reason.XMLA_SCHEMA_NAME_EXISTS );
    }
    // check if the file is a valid schema
    try {
      StringWriter writer = new StringWriter();
      IOUtils.copy( schemaInputStream, writer, "UTF8" );
      String catalogStr = writer.toString();
      makeSchema( catalogStr );
      schemaInputStream = new ByteArrayInputStream( catalogStr.getBytes() );
    } catch ( Exception ex ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0008_ERROR_OCCURRED" ), //$NON-NLS-1$
        Reason.valueOf( ex.getMessage() ) );
    }
    try {
      org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper helper =
        new org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper( PentahoSystem
          .get( IUnifiedRepository.class ) );
      helper.addSchema( schemaInputStream, catalog.getName(), catalog.getDataSourceInfo() );
    } catch ( Exception e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0008_ERROR_OCCURRED" ), //$NON-NLS-1$
        Reason.valueOf( e.getMessage() ) );
    }

    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger
        .debug( "refreshing from dataSourcesConfig (" + dataSourcesConfig + ")" ); //$NON-NLS-1$ //$NON-NLS-2$
    }
    reInit( pentahoSession );
  }

  public void importSchema( File mondrianFile, String databaseConnection, String parameters ) {

    try {
      String datasourceInfo = "Provider=mondrian;DataSource=" + databaseConnection; //$NON-NLS-1$
      if ( !StringUtils.isEmpty( parameters ) ) {
        datasourceInfo = parameters;
      }

      // Note: Mondrian parameters could be validated here and throw subsequent exception if they do not conform to
      // spec.

      FileInputStream parsingInputStream = new FileInputStream( mondrianFile );
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      org.w3c.dom.Document document = builder.parse( parsingInputStream );
      NodeList schemas = document.getElementsByTagName( "Schema" ); //$NON-NLS-1$
      Node schema = schemas.item( 0 );
      if ( schema == null ) {
        throw new SAXParseException( "",
          null ); // Generic schema error message will be provided at catch statement.
      }
      Node name = schema.getAttributes().getNamedItem( "name" ); //$NON-NLS-1$
      String catalogName = name.getTextContent();
      parsingInputStream.close();

      FileInputStream schemaInputStream = new FileInputStream( mondrianFile );
      org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper helper =
        new org.pentaho.platform.plugin.services.importexport.legacy.MondrianCatalogRepositoryHelper( PentahoSystem
          .get( IUnifiedRepository.class ) );
      helper.addSchema( schemaInputStream, catalogName, datasourceInfo );

      reInit( PentahoSessionHolder.getSession() );

    } catch ( SAXParseException e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getString(
        "MondrianCatalogHelper.ERROR_0018_IMPORT_SCHEMA_ERROR" ) ); //$NON-NLS-1$
    } catch ( Exception e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getString(
        "MondrianCatalogHelper.ERROR_0008_ERROR_OCCURRED" ), //$NON-NLS-1$
        Reason.valueOf( e.getMessage() ) );
    }
  }

  @Deprecated
  protected void writeDataSources( DataSources dataSources ) {

    File dataSourcesFile;
    try {
      dataSourcesFile = new File( new URL( dataSourcesConfig ).getFile() ); // dataSourcesConfigResource.getFile();
    } catch ( IOException e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0005_RESOURCE_NOT_AVAILABLE" ), e, Reason.GENERAL ); //$NON-NLS-1$
    }

    Writer sxml;
    try {
      sxml = new FileWriter( dataSourcesFile );
    } catch ( IOException e ) {
      throw new MondrianCatalogServiceException( e );
    }
    StringWriter sw = new StringWriter();
    XMLOutput pxml = new XMLOutput( sw );
    pxml.print( "<?xml version=\"1.0\"?>\n" ); //$NON-NLS-1$
    dataSources.displayXML( pxml, 0 );
    Document doc = null;
    try {
      doc = XmlDom4JHelper.getDocFromString( sw.toString(), new PentahoEntityResolver() );
    } catch ( XmlParseException e ) {
      throw new MondrianCatalogServiceException( e );
    }

    // pretty print
    try {
      OutputFormat format = OutputFormat.createPrettyPrint();
      format.setEncoding( doc.getXMLEncoding() );
      XMLWriter writer = new XMLWriter( sxml, format );
      writer.write( doc );
      writer.close();
      // CleanXmlHelper.saveDomToWriter(doc, sxml);
    } catch ( IOException e ) {
      throw new MondrianCatalogServiceException( e );
    }

    IOUtils.closeQuietly( sxml );
  }

  public MondrianCatalog getCatalog( final String context, final IPentahoSession pentahoSession ) {
    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger.debug( "getCatalog" ); //$NON-NLS-1$
    }
    init( pentahoSession );

    MondrianCatalog cat = getCatalogFromCache( context, pentahoSession );
    if ( null != cat ) {
      if ( hasAccess( cat, CatalogPermission.READ, pentahoSession ) ) {
        return cat;
      } else {
        if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
          MondrianCatalogHelper.logger.debug( "user requested catalog with name \"" + context //$NON-NLS-1$
            + "\", but had insufficient privileges; returning null" ); //$NON-NLS-1$
        }
        return null;
      }
    } else {
      if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
        MondrianCatalogHelper.logger
          .debug( "user requested catalog with name\"" + context
            + "\", but catalog doesn't exist" ); //$NON-NLS-1$
      }
      return null;
    }

  }

  protected void loadCatalogsIntoCache( final DataSourcesConfig.DataSources dataSources,
                                        final IPentahoSession pentahoSession ) {

    // Create the cache region if necessary.
    ICacheManager cacheMgr = PentahoSystem.getCacheManager( pentahoSession );
    if ( !cacheMgr.cacheEnabled( MONDRIAN_CATALOG_CACHE_REGION ) ) {
      // Create the region
      cacheMgr.addCacheRegion( MONDRIAN_CATALOG_CACHE_REGION );
    }
    if ( cacheMgr.getFromRegionCache( MONDRIAN_CATALOG_CACHE_REGION, getLocale().toString() ) == null ) {
      // Put the map in the region
      cacheMgr.putInRegionCache( MONDRIAN_CATALOG_CACHE_REGION, getLocale().toString(),
        new HashMap<String, List<MondrianCatalog>>() );
    }

    for ( DataSourcesConfig.DataSource dataSource : dataSources.dataSources ) {
      List<String> catalogNames = new ArrayList<String>();
      for ( DataSourcesConfig.Catalog catalog : dataSource.catalogs.catalogs ) {
        catalogNames.add( catalog.name );
      }

      Map<String, MondrianCatalog> catalogs =
        (Map<String, MondrianCatalog>) cacheMgr.getFromRegionCache( MONDRIAN_CATALOG_CACHE_REGION, getLocale()
          .toString() );

      for ( DataSourcesConfig.Catalog catalog : dataSource.catalogs.catalogs ) {
        if ( catalog.definition.startsWith( "mondrian:" ) || catalog.definition
          .startsWith( "solution:" ) ) { //$NON-NLS-1$

          // try catch here so the whole thing doesn't blow up if one datasource is configured incorrectly.
          try {
            MondrianSchema schema = makeSchema( getCatalogAsString( pentahoSession, catalog ) );

            MondrianCatalog mondrianCatalog =
              new MondrianCatalog( useSchemaNameAsCatalogName ? schema.getName() : catalog.name,
                catalog.dataSourceInfo, catalog.definition, schema );

            catalogs.put( mondrianCatalog.getName(), mondrianCatalog );
            catalogs.put( mondrianCatalog.getDefinition(), mondrianCatalog );

          } catch ( Exception e ) {
            MondrianCatalogHelper.logger.error( Messages.getInstance().getErrorString(
              "MondrianCatalogHelper.ERROR_0013_FAILED_TO_LOAD_SCHEMA", catalog.definition ), e ); //$NON-NLS-1$
          }
        } else {
          MondrianCatalogHelper.logger.warn( Messages.getInstance().getString(
            "MondrianCatalogHelper.WARN_SKIPPING_DATASOURCE_DEF", catalog.definition ) ); //$NON-NLS-1$
        }
      }
    }
  }

  protected String applyDSP( IPentahoSession ps, String catalogDsInfo, String catalogDefinition ) throws Exception {

    PropertyList pl = Util.parseConnectString( catalogDsInfo );
    String dsp = pl.get( RolapConnectionProperties.DynamicSchemaProcessor.name() );
    if ( dsp != null ) {
      if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
        MondrianCatalogHelper.logger.debug( "applyDSP: " + dsp ); //$NON-NLS-1$
      }
      DynamicSchemaProcessor dynProc = ClassResolver.INSTANCE.instantiateSafe( dsp );
      pl.put( "Locale", getLocale().toString() );
      return dynProc.processSchema( catalogDefinition, pl );
    } else {
      return docAtUrlToString( catalogDefinition, ps );
    }
  }

  protected String getCatalogAsString( IPentahoSession ps, DataSourcesConfig.Catalog catalog ) throws Exception {
    if ( catalog.dataSourceInfo != null ) {
      return applyDSP( ps, catalog.dataSourceInfo, catalog.definition );
    } else {
      MondrianCatalogHelper.logger.warn( Messages.getInstance().getString(
          "MondrianCatalogHelper.WARN_NO_CATALOG_DATASOURCE_INFO", catalog.name ) );
      return docAtUrlToString( catalog.definition, ps );
    }
  }

  @Deprecated
  protected List<MondrianCatalog> transformIntoCatalogList( final DataSourcesConfig.DataSources dataSources,
                                                            final IPentahoSession pentahoSession ) {
    List<MondrianCatalog> localCatalogs = new ArrayList<MondrianCatalog>();
    for ( DataSourcesConfig.DataSource dataSource : dataSources.dataSources ) {
      List<String> catalogNames = new ArrayList<String>();
      for ( DataSourcesConfig.Catalog catalog : dataSource.catalogs.catalogs ) {
        catalogNames.add( catalog.name );
      }

      for ( DataSourcesConfig.Catalog catalog : dataSource.catalogs.catalogs ) {
        if ( catalog.definition.startsWith( "solution:" ) ) { //$NON-NLS-1$
          // try catch here so the whole thing doesn't blow up if one datasource is configured incorrectly.
          try {
            MondrianSchema schema = makeSchema( docAtUrlToString( catalog.definition, pentahoSession ) );

            MondrianCatalogComplementInfo catalogComplementInfo = getCatalogComplementInfoMap( catalog.definition );

            MondrianCatalog mondrianCatalog =
              new MondrianCatalog( useSchemaNameAsCatalogName ? schema.getName() : catalog.name,
                catalog.dataSourceInfo, catalog.definition, schema, catalogComplementInfo );

            localCatalogs.add( mondrianCatalog );
          } catch ( Exception e ) {
            MondrianCatalogHelper.logger.error( Messages.getInstance().getErrorString(
              "MondrianCatalogHelper.ERROR_0013_FAILED_TO_LOAD_SCHEMA", catalog.definition ), e ); //$NON-NLS-1$

          }
        } else {
          MondrianCatalogHelper.logger.warn( Messages.getInstance().getString(
            "MondrianCatalogHelper.WARN_SKIPPING_DATASOURCE_DEF", catalog.definition ) ); //$NON-NLS-1$
        }
      }
    }
    return localCatalogs;
  }

  /**
   * Method to access the MondrianCatalogComplementInfo taken a catalog name.
   *
   * @param name Catalog schema location
   * @return MondrianCatalogComplementInfo object
   */
  public MondrianCatalogComplementInfo getCatalogComplementInfoMap( String name ) {
    return catalogComplementInfoMap.get( name );
  }

  /**
   * this method loads a mondrian schema
   *
   * @param solutionLocation location of the schema
   * @param pentahoSession   current session object
   * @return Mondrian Schema object.
   */
  public MondrianSchema loadMondrianSchema( final String solutionLocation, final IPentahoSession pentahoSession ) {
    return makeSchema( docAtUrlToString( solutionLocation, pentahoSession ) );
  }

  protected String docAtUrlToString( final String urlStr, final IPentahoSession pentahoSession ) {
    // String relPath = getSolutionRepositoryRelativePath(urlStr, pentahoSession);

    String res = null;
    InputStream in = null;
    try {
      LocalizingDynamicSchemaProcessor schemaProcessor = new LocalizingDynamicSchemaProcessor();
      PropertyList localeInfo = new PropertyList();
      localeInfo.put( "Locale", getLocale().toString() ); //$NON-NLS-1$

      FileSystemManager fsManager = VFS.getManager();


      SolutionRepositoryVfsFileObject mondrianDS =
        (SolutionRepositoryVfsFileObject) fsManager.resolveFile( urlStr );

      in = mondrianDS.getInputStream();
      res = schemaProcessor.filter( null, localeInfo, in );
    } catch ( FileNotFoundException fnfe ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0007_FILE_NOT_FOUND" ), fnfe ); //$NON-NLS-1$
    } catch ( Exception e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0006_IO_PROBLEM" ), e ); //$NON-NLS-1$
    } finally {
      IOUtils.closeQuietly( in );
    }
    return res;
  }

  protected MondrianSchema getSchema( final String catalogName, final IPentahoSession pentahoSession ) {
    MondrianCatalog catalog = getCatalogFromCache( catalogName, pentahoSession );
    if ( null == catalog ) {
      return null;
    } else {
      return catalog.getSchema();
    }
  }

  protected MondrianSchema makeSchema( final String catalogStr ) {
    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger
        .debug( "makeSchema (catalogStr=" + catalogStr.substring( 0, Math.min( 40, catalogStr.length() ) ) + "...)"
      );
    }
    MondrianSchema schema = null;
    try {
      final Parser xmlParser = XOMUtil.createDefaultParser();
      final DOMWrapper def = xmlParser.parse( catalogStr );
      MondrianDef.Schema schemaFromXml = new MondrianDef.Schema( def );
      String schemaName = schemaFromXml.name;
      List<MondrianCube> mondrianCubes = new ArrayList<MondrianCube>();
      for ( MondrianDef.Cube cube : schemaFromXml.cubes ) {
        if ( cube.enabled == null || cube.enabled.booleanValue() ) {
          String name = cube.caption;
          if ( StringUtils.isBlank( name ) ) {
            name = cube.name;
          }
          mondrianCubes.add( new MondrianCube( name, cube.name ) );
        }
      }
      for ( MondrianDef.VirtualCube cube : schemaFromXml.virtualCubes ) {
        String name = cube.caption;
        if ( StringUtils.isBlank( name ) ) {
          name = cube.name;
        }
        if ( cube.enabled == null || cube.enabled.booleanValue() ) {
          mondrianCubes.add( new MondrianCube( name, cube.name ) );
        }
      }

      // Interpret the role names
      MondrianDef.Role[] roles = schemaFromXml.roles;
      String[] roleNames = null;

      if ( ( roles != null ) && ( roles.length > 0 ) ) {
        roleNames = new String[ roles.length ];
        for ( int i = 0; i < roles.length; i++ ) {
          roleNames[ i ] = roles[ i ].name; // Note - getName() doesn't return the role name, it returns the word Role
        }
      }

      schema = new MondrianSchema( schemaName, mondrianCubes, roleNames );

    } catch ( XOMException e ) {
      if ( MondrianCatalogHelper.logger.isErrorEnabled() ) {
        MondrianCatalogHelper.logger.error( Messages.getInstance().getErrorString(
          "MondrianCatalogHelper.ERROR_0008_ERROR_OCCURRED" ), e ); //$NON-NLS-1$
      }
      throw Util.newError( e, Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0009_WHILE_PARSING_CATALOG", catalogStr ) ); //$NON-NLS-1$
    }
    return schema;
  }

  protected static enum CatalogPermission {
    READ, WRITE
  }

  protected List<MondrianCatalog> filter( final List<MondrianCatalog> origList, final IPentahoSession pentahoSession,
                                          final boolean jndiOnly ) {
    List<MondrianCatalog> filtered = new ArrayList<MondrianCatalog>();
    for ( MondrianCatalog orig : origList ) {
      if ( hasAccess( orig, CatalogPermission.READ, pentahoSession ) && ( !jndiOnly || orig.isJndi() ) ) {
        filtered.add( orig );
      }
    }
    return filtered;
  }

  /**
   * This (hacky) implementation bases its decision on whether or not the user has the permission (indicated by
   * <code>CatalogPermission</code>) based on whether the user has permission on the file in the solution repository
   * indicated by <code>catalog.getDefinition()</code>.
   * <p/>
   * Why is this class even enforcing security anyway!?
   */
  protected boolean hasAccess( final MondrianCatalog cat, final CatalogPermission perm,
                               final IPentahoSession pentahoSession ) {
    // IUnifiedRepository unifiedRepository = PentahoSystem.get(IUnifiedRepository.class);
    // unifiedRepository.hasAccess(null, null);
    return true;
  }

  protected String getSolutionRepositoryRelativePath( final String path, final IPentahoSession pentahoSession ) {

    try {
      FileSystemManager fsManager = VFS.getManager();
      return fsManager.resolveFile( path ).getName().getPath();
    } catch ( FileSystemException e ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0012_FILESYSTEM_PROBLEM" ), e ); //$NON-NLS-1$
    }

  }

  public boolean isUseSchemaNameAsCatalogName() {
    return useSchemaNameAsCatalogName;
  }

  public void setUseSchemaNameAsCatalogName( final boolean useSchemaNameAsCatalogName ) {
    this.useSchemaNameAsCatalogName = useSchemaNameAsCatalogName;
  }

  public static int addToCatalog( String baseUrl, boolean enableXmla, String schemaSolutionPath,
                                  IPentahoSession session, String jndiName, boolean overwrite ) {

    IMondrianCatalogService mondrianCatalogService =
      PentahoSystem.get( IMondrianCatalogService.class, "IMondrianCatalogService", session ); //$NON-NLS-1$

    String dsUrl = baseUrl;
    if ( !dsUrl.endsWith( "/" ) ) { //$NON-NLS-1$
      dsUrl += "/"; //$NON-NLS-1$
    }
    dsUrl += "Xmla"; //$NON-NLS-1$

    String catDef = "solution:" + schemaSolutionPath; //$NON-NLS-1$

    MondrianSchema mondrianSchema = mondrianCatalogService.loadMondrianSchema( catDef, session );

    String catName = mondrianSchema.getName();
    String[] roleNames = mondrianSchema.getRoleNames();

    // verify JNDI
    try {
      IDBDatasourceService datasourceService = PentahoSystem.getObjectFactory().get( IDBDatasourceService.class, null );
      datasourceService.getDSBoundName( jndiName );
    } catch ( ObjectFactoryException objface ) {
      Logger
        .error(
          "MondrianCatalogHelper", Messages.getInstance()
          .getErrorString( "MondrianCatalogPublisher.ERROR_0006_UNABLE_TO_FACTORY_OBJECT", jndiName ),
          objface );
    } catch ( DBDatasourceServiceException dse ) {
      Logger
        .error(
          "MondrianCatalogHelper",
          Messages.getInstance().getErrorString( "MondrianCatalogPublisher.ERROR_0001_JNDI_NAMING_ERROR", jndiName ),
          dse );
      return -1;
    }

    // used in both the catalog and the catalog datasource
    // Note: we use the unbound JNDI name here, the PentahoXmlaServlet resolves the JNDI name

    String catConnectStr = "Provider=mondrian;DataSource=" + jndiName; //$NON-NLS-1$

    // MB - 12/2009 - TODO: Figure out the empty list
    // Curious why we aren't adding the cubes from the read schema into the created schema.
    MondrianCatalog cat =
      new MondrianCatalog( catName, catConnectStr, catDef, new MondrianSchema( catName,
        new ArrayList<MondrianCube>(), roleNames ) );

    try {
      mondrianCatalogService.addCatalog( cat, overwrite, session );
    } catch ( MondrianCatalogServiceException e ) {
      Logger
        .error(
          "MondrianCatalogHelper",
          Messages.getInstance().getErrorString( "MondrianCatalogPublisher.ERROR_0002_EXCEPTION_OCCURRED" ),
          e );
      return -1;
    }

    return 0;
  }

  /**
   * This method removes a mondrian catalog from the JCR repository.
   */
  public void removeCatalog( final String catalogName, final IPentahoSession pentahoSession )
    throws MondrianCatalogServiceException {

    //
    // find the catalog to be removed
    //

    if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
      MondrianCatalogHelper.logger.debug( "removeCatalog" ); //$NON-NLS-1$
    }
    MondrianCatalog catalog = getCatalog( catalogName, pentahoSession );

    if ( catalog == null ) {
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0015_CATALOG_NOT_FOUND", catalogName ) ); //$NON-NLS-1$
    }

    //
    // do an access check first
    //

    if ( !hasAccess( catalog, CatalogPermission.WRITE, pentahoSession ) ) {
      if ( MondrianCatalogHelper.logger.isDebugEnabled() ) {
        MondrianCatalogHelper.logger.debug( "user does not have access; throwing exception" ); //$NON-NLS-1$
      }
      throw new MondrianCatalogServiceException( Messages.getInstance().getErrorString(
        "MondrianCatalogHelper.ERROR_0003_INSUFFICIENT_PERMISSION" ), Reason.ACCESS_DENIED ); //$NON-NLS-1$
    }

    IUnifiedRepository solutionRepository = PentahoSystem.get( IUnifiedRepository.class );
    RepositoryFile deletingFile = solutionRepository.getFile( RepositoryFile.SEPARATOR + "etc" //$NON-NLS-1$
      + RepositoryFile.SEPARATOR + "mondrian" + RepositoryFile.SEPARATOR + catalog.getName() ); //$NON-NLS-1$
    solutionRepository.deleteFile( deletingFile.getId(), true, "" ); //$NON-NLS-1$
    reInit( pentahoSession );
  }
}
TOP

Related Classes of org.pentaho.platform.plugin.action.mondrian.catalog.MondrianCatalogHelper

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.