package org.openlca.app; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.openlca.app.navigation.ModelTypeComparison; import org.openlca.app.util.Labels; import org.openlca.core.database.Daos; import org.openlca.core.database.IDatabase; import org.openlca.core.database.ParameterDao; import org.openlca.core.model.ModelType; import org.openlca.core.model.descriptors.BaseDescriptor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class Search implements Runnable { private Logger log = LoggerFactory.getLogger(getClass()); private IDatabase database; ModelType typeFilter; private String rawTerm; private String[] terms; private List<BaseDescriptor> result = new ArrayList<>(); public Search(IDatabase database, String term) { this.database = database; this.rawTerm = term == null ? "" : term.toLowerCase().trim(); terms = rawTerm.split(" "); for (int i = 0; i < terms.length; i++) terms[i] = terms[i].trim(); } public List<BaseDescriptor> getResult() { return result; } @Override public void run() { result.clear(); if (rawTerm.isEmpty()) return; log.trace("run search with term {}", rawTerm); ModelType[] types = typeFilter == null ? getSearchTypes() : new ModelType[] { typeFilter }; for (ModelType type : types) { List<?> descriptors = getDescriptors(type); fetchResults(descriptors); } Collections.sort(result, new ResultComparator()); log.trace("{} results fetched and ranked", result.size()); } private ModelType[] getSearchTypes() { return ModelTypeComparison.getOrderedTypes(); } private List<?> getDescriptors(ModelType type) { if (type == ModelType.PARAMETER) return new ParameterDao(database).getGlobalDescriptors(); return Daos.createRootDao(database, type).getDescriptors(); } private void fetchResults(List<?> descriptors) { for (Object obj : descriptors) { if (!(obj instanceof BaseDescriptor)) continue; BaseDescriptor descriptor = (BaseDescriptor) obj; if (match(descriptor)) result.add(descriptor); } } private boolean match(BaseDescriptor d) { if (terms == null) return false; if (terms.length == 1 && d.getRefId() != null && d.getRefId().equalsIgnoreCase(terms[0])) { return true; } String label = Labels.getDisplayName(d); if (label == null) return false; String feed = label.toLowerCase(); for (String term : terms) { if (!feed.contains(term)) return false; } return true; } private class ResultComparator implements Comparator<BaseDescriptor> { @Override public int compare(BaseDescriptor o1, BaseDescriptor o2) { String label1 = Labels.getDisplayName(o1).toLowerCase(); String label2 = Labels.getDisplayName(o2).toLowerCase(); for (String term : terms) { int idx1 = label1.indexOf(term); int idx2 = label2.indexOf(term); int diff = idx1 - idx2; if (diff != 0) return diff; } return label1.compareToIgnoreCase(label2); } } }