001/* 002 * Copyright 2018 Leibniz-Institut für Analytische Wissenschaften – ISAS – e.V.. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package de.isas.mztab2.validation.handlers; 017 018import de.isas.mztab2.cvmapping.CvMappingUtils; 019import static de.isas.mztab2.cvmapping.CvMappingUtils.toErrorLevel; 020import de.isas.mztab2.cvmapping.RuleEvaluationResult; 021import de.isas.mztab2.io.serialization.ParameterConverter; 022import de.isas.mztab2.model.ValidationMessage; 023import de.isas.mztab2.validation.CvTermValidationHandler; 024import info.psidev.cvmapping.CvMappingRule; 025import java.util.ArrayList; 026import java.util.Arrays; 027import java.util.HashSet; 028import java.util.List; 029import java.util.Set; 030import java.util.stream.Collectors; 031import uk.ac.ebi.pride.jmztab2.utils.errors.CrossCheckErrorType; 032import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabError; 033import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabErrorType; 034 035/** 036 * Implements 'XOR' logic, meaning mutually exclusive alternative possible terms or term roots for 037 * an object are allowed. 038 * @author nilshoffmann 039 */ 040public class XorValidationHandler implements CvTermValidationHandler { 041 042 @Override 043 public List<ValidationMessage> handleParameters(RuleEvaluationResult result, 044 boolean errorOnTermNotInRule) { 045 // xor logic means, if one of the defined terms or its children is set, none of the others is allowed 046 final List<ValidationMessage> messages = new ArrayList<>(); 047 // all defined terms or children thereof need to appear 048 Set<String> matchedParameters = new HashSet<>(); 049 matchedParameters.addAll(result.getAllowedParameters(). 050 keySet()); 051 matchedParameters.retainAll(result.getFoundParameters(). 052 keySet()); 053 if (matchedParameters.isEmpty()) { 054 for (String s : result.getAllowedParameters(). 055 keySet()) { 056 MZTabErrorType errorType = null; 057 switch (result.getRule(). 058 getRequirementLevel()) { 059 case MAY: 060 errorType = CrossCheckErrorType.CvTermOptional; 061 break; 062 case SHOULD: 063 errorType = CrossCheckErrorType.CvTermRecommended; 064 break; 065 case MUST: 066 errorType = CrossCheckErrorType.CvTermRequired; 067 break; 068 default: 069 throw new IllegalArgumentException( 070 "Unknown requirement level value: " + result. 071 getRule(). 072 getRequirementLevel() + "! Supported are: " + Arrays. 073 toString(CvMappingRule.RequirementLevel. 074 values())); 075 } 076 MZTabError error = new MZTabError(errorType, -1, 077 new ParameterConverter().convert(result. 078 getAllowedParameters(). 079 get( 080 s)), result.getRule(). 081 getCvElementPath(), CvMappingUtils. 082 niceToString( 083 result.getRule())); 084 messages.add(error.toValidationMessage()); 085 } 086 } else if (matchedParameters.size() > 1) { 087 //Only one of the provided cv terms for "{1}" {0} be reported. You defined terms "{2}". Allowed terms are defined in rule "{3}". 088 String definedParameters = matchedParameters.stream(). 089 collect(Collectors.joining(", ")); 090 MZTabErrorType xorErrorType = MZTabErrorType.forLevel( 091 MZTabErrorType.Category.CrossCheck, 092 toErrorLevel(result.getRule(). 093 getRequirementLevel()), "CvTermXor"); 094 MZTabError error = new MZTabError(xorErrorType, -1, 095 result.getRule(). 096 getRequirementLevel(). 097 value(), result.getRule(). 098 getCvElementPath(), definedParameters, 099 CvMappingUtils.niceToString(result.getRule())); 100 messages.add(error.toValidationMessage()); 101 } 102 return messages; 103 } 104}