/** * * Copyright (C) 2013 Vanderbilt University <csaba.toth, b.malin @vanderbilt.edu> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.openhie.openempi.blocking.bypass; import java.util.Iterator; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openhie.openempi.Constants; import org.openhie.openempi.blocking.RecordPairIterator; import org.openhie.openempi.context.Context; import org.openhie.openempi.matching.fellegisunter.FellegiSunterParameters; import org.openhie.openempi.matching.fellegisunter.MatchConfiguration; import org.openhie.openempi.matching.fellegisunter.MatchField; import org.openhie.openempi.matching.fellegisunter.ProbabilisticMatchingConstants; import org.openhie.openempi.matching.fellegisunter.MatchConfiguration.FieldQuerySelector; import org.openhie.openempi.model.ComparisonVector; import org.openhie.openempi.model.LeanRecordPair; import org.openhie.openempi.model.Person; import org.openhie.openempi.service.PersonQueryService; import org.openhie.openempi.stringcomparison.StringComparisonService; import org.openhie.openempi.util.GeneralUtil; public class BypassRecordPairIterator implements RecordPairIterator { protected final Log log = LogFactory.getLog(getClass()); private boolean initialized = false; private PersonQueryService personQueryService = null; private List<Person> personList = null; private Iterator<Person> personIterator = null; private Person actualPerson = null; private List<Person> personOtherList = null; private Iterator<Person> personOtherIterator = null; private StringComparisonService comparisonService = null; private List<MatchField> matchFields = null; private List<String> leftMatchFieldNames = null; private List<String> rightMatchFieldNames = null; private String leftTableName; private String rightTableName; private boolean emOnly; private FellegiSunterParameters fellegiSunterParameters; private long pageStart = 0L; private long otherPageStart = 0L; public BypassRecordPairIterator(BypassRecordPairSource recordPairSource, String leftTableName, String rightTableName, boolean emOnly, FellegiSunterParameters fellegiSunterParameters) { initialize(); this.leftTableName = leftTableName; this.rightTableName = rightTableName; this.emOnly = emOnly; this.fellegiSunterParameters = fellegiSunterParameters; } private synchronized void initialize() { if (personQueryService == null) personQueryService = Context.getPersonQueryService(); personList = null; personIterator = null; personOtherList = null; personOtherIterator = null; if (comparisonService == null) comparisonService = Context.getStringComparisonService(); pageStart = 0L; otherPageStart = 0L; initialized = true; } public LeanRecordPair next() { Person personOther = personOtherIterator.next(); ComparisonVector comparisonVector = GeneralUtil.scoreRecordPair(actualPerson, personOther, comparisonService, matchFields); LeanRecordPair recordPair = null; if (emOnly) { fellegiSunterParameters.incrementVectorFrequency(comparisonVector.getBinaryVectorValue()); } else { recordPair = new LeanRecordPair(actualPerson.getPersonId(), personOther.getPersonId()); recordPair.setComparisonVector(comparisonVector); } return recordPair; } public boolean hasNext() { return hasNext(false); } private boolean hasNext(boolean recursiveCall) { if (matchFields == null) { MatchConfiguration matchConfiguration = (MatchConfiguration)Context.getConfiguration().lookupConfigurationEntry(ProbabilisticMatchingConstants.PROBABILISTIC_MATCHING_CONFIGURATION_REGISTRY_KEY); matchFields = matchConfiguration.getMatchFields(FieldQuerySelector.MatchOnlyFields); leftMatchFieldNames = matchConfiguration.getLeftFieldNames(FieldQuerySelector.MatchOnlyFields); rightMatchFieldNames = matchConfiguration.getRightFieldNames(FieldQuerySelector.MatchOnlyFields); } if (!isInitialized()) { initialize(); } if (personIterator == null || personOtherIterator == null) { int personListSize = loadNextPersonList(personList, pageStart, personIterator, leftTableName, leftMatchFieldNames); if (personListSize <= 0) return false; if (!personIterator.hasNext()) return false; actualPerson = personIterator.next(); int personOtherListSize = loadNextPersonList(personOtherList, otherPageStart, personOtherIterator, rightTableName, rightMatchFieldNames); if (personOtherListSize <= 0) return false; if (!personOtherIterator.hasNext()) return false; return true; } else { if (personOtherIterator.hasNext()) { return true; } else { int personOtherListSize = loadNextPersonList(personOtherList, otherPageStart, personOtherIterator, rightTableName, rightMatchFieldNames); boolean needNewPerson = false; if (personOtherListSize <= 0) needNewPerson = true; if (personOtherIterator.hasNext()) return true; else needNewPerson = true; if (needNewPerson && !recursiveCall) { if (!personIterator.hasNext()) { int personListSize = loadNextPersonList(personList, pageStart, personIterator, leftTableName, leftMatchFieldNames); if (personListSize <= 0) return false; if (!personIterator.hasNext()) return false; } actualPerson = personIterator.next(); otherPageStart = 0L; return hasNext(true); } } } return false; } private int loadNextPersonList(List<Person> personListParam, long pageStartParam, Iterator<Person> personIteratorParam, String tableName, List<String> matchFieldNames) { personListParam = personQueryService.getPersonsByExamplePaged(tableName, null, matchFieldNames, pageStartParam, Constants.PAGE_SIZE); pageStartParam += Constants.PAGE_SIZE; personIteratorParam = personListParam.iterator(); return personListParam.size(); } public void remove() { // This is an optional method of the interface and doesn't do // anything in this implementation. This is a read-only iterator. } public boolean isInitialized() { return initialized; } public void setInitialized(boolean initialized) { this.initialized = initialized; } public long getTrueMatchCounter() { // TODO Auto-generated method stub return 0; } }