package org.openlca.core.database.references;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.openlca.core.database.IDatabase;
import org.openlca.core.model.Actor;
import org.openlca.core.model.CategorizedEntity;
import org.openlca.core.model.Category;
import org.openlca.core.model.Currency;
import org.openlca.core.model.DQSystem;
import org.openlca.core.model.Exchange;
import org.openlca.core.model.Flow;
import org.openlca.core.model.FlowPropertyFactor;
import org.openlca.core.model.Location;
import org.openlca.core.model.Process;
import org.openlca.core.model.ProcessDocumentation;
import org.openlca.core.model.SocialAspect;
import org.openlca.core.model.SocialIndicator;
import org.openlca.core.model.Source;
import org.openlca.core.model.Unit;
import org.openlca.core.model.descriptors.ProcessDescriptor;
public class ProcessReferenceSearch extends
BaseReferenceSearch<ProcessDescriptor> {
private final static Ref[] references = {
new Ref(Category.class, "category", "f_category", true),
new Ref(Location.class, "location", "f_location", true),
new Ref(Currency.class, "currency", "f_currency", true),
new Ref(DQSystem.class, "dqSystem", "f_dq_system", true),
new Ref(DQSystem.class, "exchangeDqSystem", "f_exchange_dq_system", true),
new Ref(DQSystem.class, "socialDqSystem", "f_social_dq_system", true),
new Ref(ProcessDocumentation.class, "documentation", "f_process_doc", true)
};
private final static Ref[] exchangeReferences = {
new Ref(Flow.class, "flow", Exchange.class, "exchanges", "f_flow"),
new Ref(FlowPropertyFactor.class, "flowPropertyFactor", Exchange.class, "exchanges",
"f_flow_property_factor"),
new Ref(Unit.class, "unit", Exchange.class, "exchanges", "f_unit"),
new Ref(Process.class, "defaultProviderId", Exchange.class, "exchanges", "f_default_provider", true, true)
};
private final static Ref[] socialAspectReferences = {
new Ref(SocialIndicator.class, "indicator", SocialAspect.class, "socialAspects", "f_indicator", false),
new Ref(Source.class, "source", SocialAspect.class, "socialAspects", "f_source", true)
};
private final static Ref[] documentationReferences = {
new Ref(Actor.class, "reviewer", ProcessDocumentation.class, "documentation", "f_reviewer", true),
new Ref(Actor.class, "dataDocumentor", ProcessDocumentation.class, "documentation", "f_data_documentor",
true),
new Ref(Actor.class, "dataGenerator", ProcessDocumentation.class, "documentation", "f_data_generator", true),
new Ref(Actor.class, "dataSetOwner", ProcessDocumentation.class, "documentation", "f_dataset_owner", true),
new Ref(Source.class, "publication", ProcessDocumentation.class, "documentation", "f_publication", true)
};
private final static Ref[] sourceReferences = {
new Ref(Source.class, "sources", ProcessDocumentation.class, "documentation", "f_source", true)
};
public ProcessReferenceSearch(IDatabase database, boolean includeOptional) {
super(database, Process.class, includeOptional);
}
@Override
public List<Reference> findReferences(Set<Long> ids) {
List<Reference> mixed = findReferences("tbl_processes", "id", ids,
references);
List<Reference> results = new ArrayList<>();
results.addAll(filter(CategorizedEntity.class, mixed));
Map<Long, Long> docIds = toIdMap(filter(ProcessDocumentation.class, mixed));
results.addAll(findExchangeReferences(ids));
results.addAll(findSocialAspectReferences(ids));
results.addAll(findDocumentationReferences(docIds));
results.addAll(findGlobalParameters(ids, getExchangeFormulas(ids)));
return results;
}
private List<Reference> findExchangeReferences(Set<Long> ids) {
Map<Long, Long> exchanges = toIdMap(findReferences("tbl_exchanges",
"f_owner", ids, new Ref[] { new Ref(Exchange.class, "id", "id") }));
return findReferences("tbl_exchanges", "id", exchanges.keySet(),
exchanges, exchangeReferences);
}
private List<Reference> findSocialAspectReferences(Set<Long> ids) {
Map<Long, Long> aspects = toIdMap(findReferences("tbl_social_aspects",
"f_process", ids, new Ref[] { new Ref(Exchange.class, "id", "id") }));
return findReferences("tbl_social_aspects", "id", aspects.keySet(),
aspects, socialAspectReferences);
}
private List<Reference> findDocumentationReferences(Map<Long, Long> map) {
List<Reference> results = new ArrayList<>();
results.addAll(findReferences("tbl_process_docs", "id", map.keySet(),
map, documentationReferences));
results.addAll(findReferences("tbl_process_sources", "f_process_doc",
map.keySet(), map, sourceReferences));
return results;
}
private Map<Long, Set<String>> getExchangeFormulas(Set<Long> ids) {
List<String> queries = Search.createQueries(
"SELECT f_owner, lower(resulting_amount_formula) FROM tbl_exchanges"
, "WHERE f_owner IN", ids);
Map<Long, Set<String>> formulas = new HashMap<>();
for (String query : queries) {
Search.on(database, null).query(query.toString(), (result) -> {
long methodId = result.getLong(1);
Set<String> set = formulas.get(methodId);
if (set == null)
formulas.put(methodId, set = new HashSet<>());
set.add(result.getString(2));
});
}
return formulas;
}
}