Changeset 5157
- Timestamp:
- 08/04/08 16:57:21 (5 months ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
openmrs-modules/patientmatching/src/org/regenstrief/linkage/io/OrderedOpenMRSReader.java
r4982 r5157 4 4 import java.util.Iterator; 5 5 import java.util.List; 6 import java.util.Properties;7 6 8 7 import org.hibernate.Query; 9 8 import org.hibernate.SessionFactory; 10 import org.hibernate.cfg.Configuration;11 9 import org.openmrs.Patient; 10 import org.openmrs.PatientIdentifierType; 12 11 import org.openmrs.PersonAttributeType; 13 12 import org.openmrs.api.context.Context; … … 16 15 import org.regenstrief.linkage.util.MatchingConfig; 17 16 17 /** 18 * identifier and attribute convention and examples: 19 * 20 * (Attribute) Birthplace 21 * (Identifer) OpenMRS Identification Number 22 * (Attribute) Credit Card Number 23 * 24 * Object fields convention and examples: 25 * 26 * org.openmrs.Person.gender 27 * org.openmrs.PersonAddress.cityVillage 28 * 29 * 30 * @author jegg 31 * 32 */ 33 18 34 public class OrderedOpenMRSReader implements OrderedDataSourceReader{ 19 35 20 36 String[] blocking_cols; 21 List<Iterator< String>> values_iterators;22 List<List< String>> blocking_values;23 List<String>current_blocking_values;37 List<Iterator<Object>> values_iterators; 38 List<List<Object>> blocking_values; 39 Object[] current_blocking_values; 24 40 List<Integer> value_set; 25 41 42 public final static String ATTRIBUTE_PREFIX = "(Attribute) "; 43 public final static String IDENT_PREFIX = "(Identifier)"; 44 26 45 private SessionFactory sessionFactory; 27 46 28 public OrderedOpenMRSReader(MatchingConfig mc ){29 // need to initialize sessionFactory to avoid null pointer exception when issuing query30 31 values_iterators = new ArrayList<Iterator< String>>();47 public OrderedOpenMRSReader(MatchingConfig mc, SessionFactory session_factory){ 48 sessionFactory = session_factory; 49 50 values_iterators = new ArrayList<Iterator<Object>>(); 32 51 value_set = new ArrayList<Integer>(); 33 current_blocking_values = new ArrayList<String>();34 52 35 53 blocking_cols = mc.getBlockingColumns(); 36 blocking_values = new ArrayList<List<String>>(); 54 blocking_values = new ArrayList<List<Object>>(); 55 56 current_blocking_values = new Object[blocking_cols.length]; 37 57 38 58 for(int i = 0; i < blocking_cols.length; i++){ 39 List<String> values = getDemographicValues(blocking_cols[i]); 59 List<Object> query_values = getDemographicValues(blocking_cols[i]); 60 Iterator<Object> it = query_values.iterator(); 61 List<Object> values = new ArrayList<Object>(); 62 while(it.hasNext()){ 63 Object obj = it.next(); 64 values.add(obj); 65 } 40 66 blocking_values.add(values); 41 67 values_iterators.add(values.iterator()); 42 68 } 69 70 // initial increment and blocking value assignment 71 for(int i = values_iterators.size() - 1; i >= 0; i--){ 72 Iterator<Object> it = values_iterators.get(i); 73 Object new_block_val = it.next(); 74 current_blocking_values[i] = new_block_val; 75 } 76 77 while(fillIDValueSet() < 1 && incrementIterators()){ 78 // do until IDs are set, or iterators are all incremented 79 } 80 43 81 } 44 82 … … 68 106 } 69 107 108 protected int fillIDValueSet(){ 109 value_set = getPatientIDs(blocking_cols[0], current_blocking_values[0]); 110 int col = 1; 111 while(value_set.size() > 0 && col < blocking_cols.length){ 112 value_set.retainAll(getPatientIDs(blocking_cols[col], current_blocking_values[col])); 113 col++; 114 } 115 116 return value_set.size(); 117 } 118 70 119 public Record nextRecord(){ 71 120 // possible future optimization - remove values from blocking_values if all references 72 121 // to a value has been read 73 122 74 boolean has_record = value_set.size() > 0;75 while(!has_record){76 // need to increment the least significant iterator, or restart iterators, until we find77 // IDs at the combination, or78 if(incrementedIterators()){79 // get the set of IDs at the current values80 value_set = getPatientIDs(blocking_cols[0], current_blocking_values.get(0));81 int col = 1;82 while(value_set.size() > 0 && col < blocking_cols.length){83 value_set.retainAll(getPatientIDs(blocking_cols[1], current_blocking_values.get(1)));84 }85 if(value_set.size() > 0){86 has_record = true;87 }88 } else {89 // at the end of values90 return null;91 }92 }93 94 // if there are IDs in the value_set, then return a Record of one of the IDs95 123 if(value_set.size() > 0){ 96 124 Integer id = value_set.remove(0); 97 125 Patient p = Context.getPatientService().getPatient(id); 126 127 if(value_set.size() == 0){ 128 // removed last ID at this point in blocking values, need to increment iterators and refill 129 // value_set 130 while(incrementIterators() && fillIDValueSet() < 1){ 131 // do until IDs are set, or iterators are all incremented 132 } 133 } 98 134 return PatientMatchingActivator.patientToRecord(p); 99 135 } … … 102 138 } 103 139 104 protected boolean increment edIterators(){140 protected boolean incrementIterators(){ 105 141 for(int i = values_iterators.size() - 1; i >= 0; i--){ 106 Iterator< String> it = values_iterators.get(i);142 Iterator<Object> it = values_iterators.get(i); 107 143 if(it.hasNext()){ 108 Stringnew_block_val = it.next();109 current_blocking_values .set(i, new_block_val);144 Object new_block_val = it.next(); 145 current_blocking_values[i] = new_block_val; 110 146 return true; 111 147 } else { … … 121 157 * @return 122 158 */ 123 private List<String> getDemographicValues(String demographic){ 124 List<String> ret = null; 125 // need to see if demographic refers to a datamodel table value, or an attribute 159 private List<Object> getDemographicValues(String demographic){ 160 List<Object> ret = null; 161 String query_text = new String(); 162 // need to see if demographic refers to a data model table value, or an attribute 126 163 if(demographic.contains(".")){ 127 164 // need to query the table name before the . for the field 128 String[] table_field = demographic.split("\\."); 129 if(table_field != null && table_field.length == 2){ 130 String query_text = "HQLQUERY: " + "select distinct t." + table_field[1] + " from " + table_field[0] + " t"; 131 System.out.println(query_text); 132 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 133 ret = (List<String>)q.list(); 134 } 165 String[] object_field = demographic.split("\\."); 166 String object_name = object_field[0]; 167 String field = object_field[object_field.length - 1]; 168 for(int i = 1; i < object_field.length - 1; i++){ 169 object_name += "." + object_field[i]; 170 } 171 172 query_text = "SELECT DISTINCT o." + field + " FROM " + object_name + " o"; 173 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 174 ret = q.list(); 135 175 } else { 136 // get the various attribute values from the person attribute table 137 PersonAttributeType pat = Context.getPersonService().getPersonAttributeType(demographic); 138 if(pat != null){ 139 // HQL query to get all values 140 // something like 141 // select distinct value from person_attribute where person_attribute_type_id = <id> 142 Query q = sessionFactory.getCurrentSession().createQuery("select distinct p.value from person_attribute p where p.person_attribute_type_id = :attr_id "); 143 q.setInteger("attr_id", pat.getPersonAttributeTypeId()); 144 ret = (List<String>)q.list(); 145 } 146 } 176 if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 177 // need to look at attribute type first to get the right query 178 String attr = stripType(demographic); 179 PersonAttributeType pat = Context.getPersonService().getPersonAttributeType(attr); 180 if(pat != null){ 181 // HQL query to get all values 182 // something like 183 // select distinct value from person_attribute where person_attribute_type_id = <id> 184 int id = pat.getPersonAttributeTypeId(); 185 query_text = "SELECT DISTINCT p.value FROM PersonAttribute p WHERE p.attributeID = " + id; 186 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 187 ret = q.list(); 188 } 189 } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 190 // need to look at identifier types first to get right query 191 String ident = stripType(demographic); 192 PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierType(ident); 193 if(pit != null){ 194 // HQL query to get all values 195 int id = pit.getPatientIdentifierTypeId(); 196 query_text = "SELECT DISTINCT p.value FROM PatientIdentifier p WHERE p.typeID = " + id; 197 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 198 ret = q.list(); 199 } 200 } 201 202 } 203 147 204 return ret; 205 } 206 207 private String stripType(String type_name){ 208 // method strips the first 209 if(type_name.indexOf(ATTRIBUTE_PREFIX) != -1){ 210 return type_name.replaceFirst(ATTRIBUTE_PREFIX,""); 211 } else if(type_name.indexOf(IDENT_PREFIX) != -1){ 212 return type_name.replaceFirst(IDENT_PREFIX, ""); 213 } 214 return type_name; 148 215 } 149 216 … … 155 222 * @return 156 223 */ 157 private List<Integer> getPatientIDs(String demographic, Stringvalue){224 private List<Integer> getPatientIDs(String demographic, Object value){ 158 225 List<Integer> ret = null; 226 String query_text = new String(); 159 227 // get patient IDs using HQL that have this value for 160 228 // this demographic 161 229 if(demographic.contains(".")){ 162 230 // need to query the table name before the . for the field 163 String[] table_field = demographic.split("\\."); 164 if(table_field != null && table_field.length == 2){ 165 Query q = sessionFactory.getCurrentSession().createQuery("select distinct person_id from " + table_field[0] + " where " + table_field[1] + " = :value"); 166 q.setString("value", value); 167 ret = (List<Integer>)q.list(); 168 } 231 String[] object_field = demographic.split("\\."); 232 String object_name = object_field[0]; 233 String field = object_field[object_field.length - 1]; 234 for(int i = 1; i < object_field.length - 1; i++){ 235 object_name += "." + object_field[i]; 236 } 237 238 query_text = "SELECT o.personID FROM " + object_name + " o WHERE " + field + " =:value"; 239 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 240 q.setEntity("value", value); 241 ret = new ArrayList<Integer>(); 242 ret.addAll(q.list()); 169 243 } else { 170 // get the various attribute values from the person attribute table 171 PersonAttributeType pat = Context.getPersonService().getPersonAttributeType(demographic); 172 Query q = sessionFactory.getCurrentSession().createQuery("select distinct p.person_id from person_attribute p where p.person_attribute_type_id = :attr_id and p.attribute = :value"); 173 q.setString("value", value); 174 q.setInteger("attr_id", pat.getPersonAttributeTypeId()); 175 ret = (List<Integer>)q.list(); 176 } 244 if(demographic.indexOf(ATTRIBUTE_PREFIX) != -1){ 245 // need to look at attribute type first to get the right query 246 String attr = stripType(demographic); 247 PersonAttributeType pat = Context.getPersonService().getPersonAttributeType(attr); 248 if(pat != null){ 249 // HQL query to get all values 250 // something like 251 // select distinct value from person_attribute where person_attribute_type_id = <id> 252 int id = pat.getPersonAttributeTypeId(); 253 query_text = "SELECT DISTINCT p.personID FROM PersonAttribute p WHERE p.value = :value"; 254 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 255 q.setEntity("value", value); 256 ret = new ArrayList<Integer>(); 257 ret.addAll(q.list()); 258 } 259 } else if(demographic.indexOf(IDENT_PREFIX) != -1){ 260 // need to look at identifier types first to get right query 261 String ident = stripType(demographic); 262 PatientIdentifierType pit = Context.getPatientService().getPatientIdentifierType(ident); 263 if(pit != null){ 264 // HQL query to get all values 265 int id = pit.getPatientIdentifierTypeId(); 266 query_text = "SELECT DISTINCT p.personID FROM PatientIdentifier p WHERE p.value = :value"; 267 Query q = sessionFactory.getCurrentSession().createQuery(query_text); 268 q.setEntity("value", value); 269 ret = new ArrayList<Integer>(); 270 ret.addAll(q.list()); 271 } 272 } 273 274 } 275 177 276 return ret; 178 277 } 278 179 279 }