001 /* 002 // $Id: //open/mondrian/src/main/mondrian/spi/impl/DataSourceChangeListenerImpl4.java#6 $ 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) 2005-2008 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 java.util.Random; 013 014 import mondrian.spi.DataSourceChangeListener; 015 import mondrian.olap.MondrianDef; 016 import mondrian.rolap.RolapHierarchy; 017 import mondrian.rolap.agg.Aggregation; 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; DataSourceChangeListener=com.acme.MyChangeListener; 036 * </code></blockquote> 037 * 038 * This class should be called in mondrian before any data is read, so 039 * even before cache is build. This way, the plugin is able to register 040 * the first timestamp mondrian tries to read the datasource. 041 * 042 * @author Bart Pappyn 043 * @version $Id: //open/mondrian/src/main/mondrian/spi/impl/DataSourceChangeListenerImpl4.java#6 $ 044 * @since Dec 12, 2006 045 */ 046 047 public 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 public DataSourceChangeListenerImpl4(int flushInverseFrequencyHierarchy, 057 int flushInverseFrequencyAggregation) { 058 this.flushInverseFrequencyHierarchy = flushInverseFrequencyHierarchy; 059 this.flushInverseFrequencyAggregation = flushInverseFrequencyAggregation; 060 } 061 062 public synchronized boolean isHierarchyChanged(RolapHierarchy hierarchy) { 063 if (flushInverseFrequencyHierarchy != 0) { 064 if (random.nextInt(flushInverseFrequencyHierarchy) == 0) { 065 return true; 066 } else { 067 return false; 068 } 069 } else { 070 return true; 071 } 072 } 073 074 public synchronized boolean isAggregationChanged(Aggregation aggregation) { 075 if (flushInverseFrequencyAggregation != 0) { 076 if (random.nextInt(flushInverseFrequencyAggregation) == 0) { 077 return true; 078 } else { 079 return false; 080 } 081 } else { 082 return true; 083 } 084 } 085 086 public String getTableName(RolapHierarchy hierarchy) { 087 MondrianDef.RelationOrJoin relation = hierarchy.getRelation(); 088 if (relation instanceof MondrianDef.Table) { 089 MondrianDef.Table tableRelation = (MondrianDef.Table)relation; 090 return tableRelation.name; 091 } else { 092 return null; 093 } 094 } 095 } 096 097 // End DataSourceChangeListenerImpl4.java