/* * Copyright 2009-2013 European Molecular Biology Laboratory * * 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 uk.ac.ebi.fg.annotare2.magetabcheck.checker; import com.google.common.collect.Maps; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import uk.ac.ebi.fg.annotare2.magetabcheck.model.Experiment; import uk.ac.ebi.fg.annotare2.magetabcheck.model.idf.IdfData; import uk.ac.ebi.fg.annotare2.magetabcheck.model.sdrf.*; import java.util.*; import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Maps.newHashMap; import static com.google.common.collect.Queues.newArrayDeque; import static com.google.common.collect.Sets.newHashSet; /** * @author Olga Melnichuk */ public class Checker { private final ExperimentType invType; private final List<CheckDefinition> allChecks = newArrayList(); private List<CheckRunWatcher> watchers; @Inject public Checker(List<CheckDefinition> allChecks, @Assisted ExperimentType type) { this.invType = type; this.allChecks.addAll(allChecks); } public Collection<CheckResult> check(Experiment exp) { watchers = newArrayList(); for (CheckDefinition cd : allChecks) { watchers.add(new CheckRunWatcher(cd)); } check(exp.getIdfData()); check(exp.getSdrfGraph()); return summarize(); } private void check(IdfData idf) { if (idf == null) { return; } checkOne(idf.getInfo()); checkAll(idf.getComments()); checkAll(idf.getContacts()); checkAll(idf.getExperimentDesigns()); checkAll(idf.getExperimentalFactors()); checkAll(idf.getQualityControlTypes()); checkAll(idf.getReplicateTypes()); checkAll(idf.getNormalizationTypes()); checkAll(idf.getProtocols()); checkAll(idf.getPublications()); checkAll(idf.getTermSources()); } private void check(SdrfGraph graph) { if (graph == null) { return; } Set<SdrfGraphEntity> visited = newHashSet(); Queue<SdrfGraphNode> queue = newArrayDeque(); queue.addAll(graph.getRootNodes()); while (!queue.isEmpty()) { SdrfGraphNode node = queue.poll(); if (visited.contains(node)) { continue; } checkOne(node); checkAttributes(node, visited); visited.add(node); for (SdrfGraphNode n : node.getChildNodes()) { queue.add(n); } } } private void checkAttributes(HasAttributes obj, Set<SdrfGraphEntity> marks) { for (SdrfGraphAttribute attr : obj.getAttributes()) { if (marks.contains(attr)) { continue; } checkOne(attr); marks.add(attr); checkAttributes(attr, marks); } } private <T> void checkAll(Collection<T> collection) { for (T item : collection) { checkOne(item); } } private <T> void checkOne(T item) { for (CheckRunWatcher watcher : watchers) { watcher.run(item, invType); } } private List<CheckResult> summarize() { List<CheckResult> results = newArrayList(); for (CheckRunWatcher watcher : watchers) { results.addAll(watcher.summarize()); } return results; } private static class CheckRunWatcher { private final CheckDefinition def; private Map<Class<?>, CheckRunner<?>> runners; private Map<Class<?>, Object> targets; private final List<CheckResult> results; private CheckRunWatcher(CheckDefinition def) { this.def = def; results = newArrayList(); targets = newHashMap(); runners = newHashMap(); } @SuppressWarnings("unchecked") public <T> void run(T item, ExperimentType invType) { if (!def.isApplicable(item.getClass(), invType)) { return; } CheckRunner<T> runner; Object target; if (targets.containsKey(def.getCheckClass())) { target = targets.get(def.getCheckClass()); } else { target = def.getCheckInstance(); targets.put(def.getCheckClass(), target); } if (def.getType().isClassBased()) { if (runners.containsKey(item.getClass())) { runner = ((CheckRunner<T>) runners.get(item.getClass())); } else { runner = (CheckRunner<T>) def.newRunner(item.getClass(), target); runners.put(item.getClass(), runner); } } else { runner = (CheckRunner<T>) def.newRunner(item.getClass(), target); } runner.runWith(item, Maps.<Class<?>, Object>newHashMap()); if (!def.getType().isClassBased()) { sumUp(runner.sumUp()); } } public List<CheckResult> summarize() { if (def.getType().isClassBased()) { for(CheckRunner<?> runner : runners.values()) { sumUp(runner.sumUp()); } } return results; } private void sumUp(List<CheckResult> checkResults) { results.addAll(checkResults); } } }