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