Java tutorial
/* * #%L * Eureka Protempa ETL * %% * Copyright (C) 2012 - 2013 Emory University * %% * This program is dual licensed under the Apache 2 and GPLv3 licenses. * * Apache License, Version 2.0: * * 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. * * GNU General Public License version 3: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package edu.emory.cci.aiw.cvrg.eureka.etl.ksb; import edu.emory.cci.aiw.cvrg.eureka.etl.config.EtlProperties; import edu.emory.cci.aiw.cvrg.eureka.etl.config.EurekaProtempaConfigurations; import org.protempa.KnowledgeSource; import org.protempa.KnowledgeSourceReadException; import org.protempa.PropositionDefinition; import org.protempa.SourceFactory; import org.protempa.backend.BackendInitializationException; import org.protempa.backend.BackendNewInstanceException; import org.protempa.backend.BackendProviderSpecLoaderException; import org.protempa.backend.Configurations; import org.protempa.backend.ConfigurationsLoadException; import org.protempa.backend.ConfigurationsNotFoundException; import org.protempa.backend.InvalidConfigurationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.Stack; import org.apache.commons.collections4.map.ReferenceMap; import org.protempa.SourceCloseException; public class PropositionDefinitionFinder implements AutoCloseable { private static final Logger LOGGER = LoggerFactory.getLogger(PropositionDefinitionFinder.class); private static final Map<String, List<PropositionDefinition>> parentsCache = new ReferenceMap<>(); private final KnowledgeSource knowledgeSource; private final EtlProperties etlProperties; private final Set<String> defaultProps; public PropositionDefinitionFinder(String configId, EtlProperties etlProperties) throws PropositionFinderException { this.etlProperties = etlProperties; try { this.validateConfigDir(etlProperties.getSourceConfigDirectory()); LOGGER.debug("Creating new configurations, source factory, and knowledge source"); Configurations configurations = new EurekaProtempaConfigurations(etlProperties); SourceFactory sf = new SourceFactory(configurations, configId); this.knowledgeSource = sf.newKnowledgeSourceInstance(); this.defaultProps = new HashSet<>(this.etlProperties.getDefaultSystemPropositions()); LOGGER.debug("Done: configurations, source factory, and knowledge source created"); } catch (IOException | ConfigurationsNotFoundException | BackendInitializationException | BackendNewInstanceException | ConfigurationsLoadException | InvalidConfigurationException | BackendProviderSpecLoaderException ex) { throw new PropositionFinderException(ex); } } public List<PropositionDefinition> findAll(Collection<String> propIds) throws PropositionFinderException { try { return this.knowledgeSource.readPropositionDefinitions(propIds.toArray(new String[propIds.size()])); } catch (KnowledgeSourceReadException e) { throw new PropositionFinderException(e); } } public PropositionDefinition find(String inKey) throws PropositionFinderException { PropositionDefinition definition = null; try { definition = this.knowledgeSource.readPropositionDefinition(inKey); } catch (KnowledgeSourceReadException e) { throw new PropositionFinderException(e); } return definition; } public List<String> searchPropositions(String inSearchKey) throws PropositionFinderException { LinkedHashSet<String> nodesToLoad = new LinkedHashSet<>(); try { List<PropositionDefinition> searchResults = knowledgeSource .getMatchingPropositionDefinitions(inSearchKey); for (PropositionDefinition pf : searchResults) { if (nodesToLoad.size() > etlProperties.getSearchLimit()) { break; } else { if (pf != null) { readParentsForSearchResult(pf, nodesToLoad); } } } } catch (KnowledgeSourceReadException e) { throw new PropositionFinderException(e); } return new ArrayList<>(nodesToLoad); } public List<PropositionDefinition> getPropositionsBySearchKey(String inSearchKey) throws PropositionFinderException { List<PropositionDefinition> nodesToLoad = new ArrayList<PropositionDefinition>(); try { nodesToLoad = knowledgeSource.getMatchingPropositionDefinitions(inSearchKey); } catch (KnowledgeSourceReadException e) { throw new PropositionFinderException(e); } return nodesToLoad; } @Override public void close() throws PropositionFinderException { try { this.knowledgeSource.close(); } catch (SourceCloseException ex) { throw new PropositionFinderException(ex); } } private void readParentsForSearchResult(PropositionDefinition pf, LinkedHashSet<String> nodesToLoad) throws PropositionFinderException { try { Queue<PropositionDefinition> toProcessQueue = new LinkedList<>(); Stack<String> processedStack = new Stack<>(); toProcessQueue.add(pf); while (!toProcessQueue.isEmpty()) { PropositionDefinition currentPropDef = toProcessQueue.remove(); List<PropositionDefinition> parents; synchronized (parentsCache) { parents = parentsCache.get(currentPropDef.getId()); if (parents == null) { parents = knowledgeSource.readParents(currentPropDef); parentsCache.put(currentPropDef.getId(), parents); } } for (PropositionDefinition parent : parents) { toProcessQueue.add(parent); processedStack.add(parent.getId()); } } getNodesToLoad(processedStack, nodesToLoad); } catch (KnowledgeSourceReadException e) { throw new PropositionFinderException(e); } } private void getNodesToLoad(Stack<String> processedStack, LinkedHashSet<String> nodesToLoad) { while (!processedStack.empty()) { String node = processedStack.pop(); if (!nodesToLoad.contains(node)) { if (defaultProps.contains(node)) { nodesToLoad.add(node); } else { List<PropositionDefinition> parents; synchronized (parentsCache) { parents = parentsCache.get(node); } if (parents != null) { for (PropositionDefinition parent : parents) { if (nodesToLoad.contains(parent.getId())) { nodesToLoad.add(node); break; } } } } } } } private void validateConfigDir(File inFile) { if (LOGGER.isErrorEnabled()) { if (!inFile.exists()) { LOGGER.error("Configuration directory " + inFile.getAbsolutePath() + " does not exist. Proposition finding will not work" + " without it. Please create it and try again."); } else if (!inFile.isDirectory()) { LOGGER.error("Path " + inFile.getAbsolutePath() + " is not a " + "directory. Proposition finding requires it to be a" + " directory."); } } } }