001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2005-2009 Pentaho
008// All Rights Reserved.
009*/
010package mondrian.spi.impl;
011
012import mondrian.olap.MondrianDef;
013import mondrian.rolap.RolapHierarchy;
014import mondrian.rolap.agg.AggregationKey;
015import mondrian.spi.DataSourceChangeListener;
016
017import java.util.Random;
018
019
020/**
021 * Default implementation of a data source change listener
022 * that always returns that the datasource is changed.
023 *
024 * A change listener can be specified in the connection string.  It is used
025 * to ask what is changed in the datasource (e.g. database).
026 *
027 * Everytime mondrian has to decide whether it will use data from cache, it
028 * will call the change listener.  When the change listener tells mondrian
029 * the datasource has changed for a dimension, cube, ... then mondrian will
030 * flush the cache and read from database again.
031 *
032 * It is specified in the connection string, like this:
033 *
034 * <blockquote><code>
035 * Jdbc=jdbc:odbc:MondrianFoodMart; JdbcUser=ziggy; JdbcPassword=stardust;
036 * DataSourceChangeListener=com.acme.MyChangeListener;
037 * </code></blockquote>
038 *
039 * This class should be called in mondrian before any data is read, so
040 * even before cache is build.  This way, the plugin is able to register
041 * the first timestamp mondrian tries to read the datasource.
042 *
043 * @author Bart Pappyn
044 * @since Dec 12, 2006
045 */
046
047public class DataSourceChangeListenerImpl4 implements DataSourceChangeListener {
048    private int flushInverseFrequencyHierarchy;
049    private int flushInverseFrequencyAggregation;
050    final Random random = new Random(123456);
051
052    /** Creates a new instance of DataSourceChangeListenerImpl2 */
053    public DataSourceChangeListenerImpl4() {
054        this(0, 0);
055    }
056
057    public DataSourceChangeListenerImpl4(
058        int flushInverseFrequencyHierarchy,
059        int flushInverseFrequencyAggregation)
060    {
061        this.flushInverseFrequencyHierarchy = flushInverseFrequencyHierarchy;
062        this.flushInverseFrequencyAggregation =
063            flushInverseFrequencyAggregation;
064    }
065
066    public synchronized boolean isHierarchyChanged(RolapHierarchy hierarchy) {
067        if (flushInverseFrequencyHierarchy != 0) {
068            if (random.nextInt(flushInverseFrequencyHierarchy) == 0) {
069                return true;
070            } else {
071                return false;
072            }
073        } else {
074            return true;
075        }
076    }
077
078    public synchronized boolean isAggregationChanged(
079        AggregationKey aggregation)
080    {
081        if (flushInverseFrequencyAggregation != 0) {
082            if (random.nextInt(flushInverseFrequencyAggregation) == 0) {
083                return true;
084            } else {
085                return false;
086            }
087        } else {
088            return true;
089        }
090    }
091
092    public String getTableName(RolapHierarchy hierarchy) {
093        MondrianDef.RelationOrJoin relation = hierarchy.getRelation();
094        if (relation instanceof MondrianDef.Table) {
095            MondrianDef.Table tableRelation = (MondrianDef.Table)relation;
096            return tableRelation.name;
097        } else {
098            return null;
099        }
100    }
101}
102
103// End DataSourceChangeListenerImpl4.java