001 /** 002 * 003 */ 004 package org.wdssii.core; 005 006 import java.util.Date; 007 import java.util.HashMap; 008 import java.util.HashSet; 009 import java.util.Map; 010 import java.util.Set; 011 import java.util.SortedMap; 012 import java.util.TreeMap; 013 014 // import org.apache.commons.logging.Log; 015 // import org.apache.commons.logging.LogFactory; 016 017 /** 018 * the Index class connects to a data source and provides access to real-time 019 * products as they come in. 020 * 021 * @author Lakshman 022 * @version $Id: Index.java,v 1.6 2006/12/29 21:15:12 lakshman Exp $ 023 * @see IndexRecord 024 */ 025 public abstract class Index { 026 // private static Log log = LogFactory.getLog(Index.class); 027 028 /** 029 * Create a brand-new Index with these listeners attached. 030 */ 031 public abstract Index newInstance(String path, 032 Set<IndexRecordListener> listeners) throws DataUnavailableException; 033 034 /** 035 * The update() method will be called periodically. The implementation is 036 * allowed to ignore update() calls that happen at inconvenient times. 037 */ 038 public abstract void update(); 039 040 /** datatype to TreeMap<time,record> */ 041 private HashMap<String, TreeMap<Date, IndexRecord>> timestamps = new HashMap<String, TreeMap<Date, IndexRecord>>(); 042 043 private HashMap<String, IndexRecord> records = new HashMap<String, IndexRecord>(); 044 045 private HashMap<String, HashSet<String>> selections = new HashMap<String, HashSet<String>>(); 046 047 private HashSet<String> datatypes = new HashSet<String>(); 048 049 private Set<IndexRecordListener> listeners = null; 050 051 private String indexLocation = null; 052 053 /** the directory in which this index.xml or index.lb is located */ 054 public String getIndexLocation() { 055 return indexLocation; 056 } 057 058 public Index(String indexLocation, Set<IndexRecordListener> listeners) { 059 this.indexLocation = indexLocation; 060 this.listeners = listeners; 061 } 062 063 /** Register a listener to be notified about new records in this index. */ 064 public void addRecordListener(IndexRecordListener listener) { 065 listeners.add(listener); 066 } 067 068 public void addRecord(IndexRecord rec) { 069 // form the selections to create the keys 070 String[] sels = new String[3]; 071 sels[0] = rec.getDataType(); // dt 072 sels[1] = rec.getSubType(); 073 sels[2] = rec.getTimeStamp(); 074 075 addSelection(getKey(sels, 0, 0), sels[1]); 076 addSelection(getKey(sels, 0, 1), sels[2]); 077 addRecord(getKey(sels, 0, 2), rec); // everything to record 078 079 datatypes.add(sels[0]); 080 081 addRecByTypeTime(rec.getTime(), sels[0], rec); 082 083 for (IndexRecordListener listener : listeners) { 084 listener.handleRecord(rec); 085 } 086 } 087 088 void addRecByTypeTime(Date time, String dt, IndexRecord rec) { 089 TreeMap<Date, IndexRecord> tm = timestamps.get(dt); 090 if (tm == null) { 091 tm = new TreeMap<Date, IndexRecord>(); 092 timestamps.put(dt, tm); 093 } 094 tm.put(time, rec); 095 } 096 097 private String getKey(String[] sels, int start, int last) { 098 StringBuilder b = new StringBuilder(); 099 for (int i = start; i <= last; ++i) { 100 b.append(sels[i]); 101 b.append(" "); 102 } 103 return b.toString(); 104 } 105 106 // note that from is INCLUSIVE and to is EXCLUSIVE 107 108 public Map<Date, IndexRecord> getRecordsByTypeTime(String dt, Date from, 109 Date to) { 110 TreeMap<Date, IndexRecord> tm = timestamps.get(dt); 111 if (tm == null) 112 return null; 113 114 SortedMap<Date, IndexRecord> sm = null; 115 if (from != null) { 116 if (to != null) 117 sm = tm.subMap(from, to); 118 else 119 sm = tm.tailMap(from); 120 } else { 121 if (to != null) 122 sm = tm.headMap(to); 123 else 124 sm = tm; 125 } 126 return (sm); 127 } 128 129 public IndexRecord getFirstRecordByTime(String dt) { 130 TreeMap<Date, IndexRecord> tm = timestamps.get(dt); 131 if (tm == null) 132 return null; 133 return tm.get(tm.firstKey()); 134 } 135 136 public IndexRecord getLastRecordByTime(String dt) { 137 TreeMap<Date, IndexRecord> tm = timestamps.get(dt); 138 if (tm == null) 139 return null; 140 return tm.get(tm.lastKey()); 141 } 142 143 public int numRecordsByTime(String dt) { 144 TreeMap<Date, IndexRecord> tm = timestamps.get(dt); 145 if (tm == null) 146 return -1; 147 return (tm.size()); 148 } 149 150 private void addSelection(String key, String s) { 151 HashSet<String> inmap = selections.get(key); 152 if (inmap == null) { 153 inmap = new HashSet<String>(); 154 selections.put(key, inmap); 155 } 156 inmap.add(s); 157 } 158 159 private void addRecord(String key, IndexRecord rec) { 160 records.put(key, rec); 161 } 162 163 public IndexRecord getRecord(String[] selections) { 164 return getRecord(getKey(selections, 0, 2)); 165 } 166 167 public IndexRecord getRecord(String key) { 168 return records.get(key); 169 } 170 171 public Set<String> getDataTypes() { 172 return datatypes; 173 } 174 175 public Set<String> getNextSelection(String[] selections) { 176 return getNextSelection(getKey(selections, 0, selections.length - 1)); 177 } 178 179 public Set<String> getNextSelection(String key) { 180 return selections.get(key); 181 } 182 183 }