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.cvmapping;
017
018import de.isas.mztab2.model.Parameter;
019import info.psidev.cvmapping.CvMappingRule;
020import info.psidev.cvmapping.CvTerm;
021import java.util.List;
022import java.util.stream.Collectors;
023import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabErrorType;
024import uk.ac.ebi.pride.utilities.ols.web.service.model.Term;
025
026/**
027 * Utility methods for conversion between the mapping file domain and the mzTab
028 * domain.
029 *
030 * @author nilshoffmann
031 */
032public class CvMappingUtils {
033
034    /**
035     * Maps the provided requirement level to the corresponding MZTabErrorType.Level.
036     * @param requirementLevel the requirement level
037     * @return the corresponding error type level
038     */
039    public static MZTabErrorType.Level toErrorLevel(
040        CvMappingRule.RequirementLevel requirementLevel) {
041        switch (requirementLevel) {
042            case MAY:
043                return MZTabErrorType.Level.Info;
044            case SHOULD:
045                return MZTabErrorType.Level.Warn;
046            case MUST:
047                return MZTabErrorType.Level.Error;
048            default:
049                throw new IllegalArgumentException(
050                    "Unhandled case: " + requirementLevel);
051        }
052    }
053
054    /**
055     * Creates a user-friendly string of a mapping rule.
056     * @param rule the cv mapping rule
057     * @return the string representation
058     */
059    public static String niceToString(CvMappingRule rule) {
060        StringBuilder sb = new StringBuilder();
061        switch (rule.getRequirementLevel()) {
062            case MAY:
063                sb.append("OPTIONAL ");
064                break;
065            case SHOULD:
066                sb.append("RECOMMENDED ");
067                break;
068            case MUST:
069                sb.append("REQUIRED ");
070                break;
071        }
072
073        sb.append("rule '").
074            append(rule.getId()).
075            append("' for path '").
076            append(rule.getCvElementPath()).
077            append("' and with scope '").
078            append(rule.getScopePath()).
079            append("' ");
080
081        sb.append(" matching ");
082        switch (rule.getCvTermsCombinationLogic()) {
083            case AND:
084                sb.append(" ALL of");
085                break;
086            case OR:
087                sb.append(" ANY of");
088                break;
089            case XOR:
090                sb.append(" EXACTLY ONE of");
091                break;
092        }
093        sb.append(" the terms ");
094        sb.append(rule.getCvTerm().
095            stream().
096            map((term) ->
097            {
098                StringBuilder termString = new StringBuilder();
099                termString.append(" '").
100                    append(term.getTermAccession()).
101                    append("' with name '").
102                    append(term.getTermName()).
103                    append("'");
104
105                if (term.isAllowChildren()) {
106                    if (term.isUseTerm()) {
107                        termString.append(
108                            " including itself or any of its children.");
109                    } else {
110                        termString.append(
111                            " excluding itself but including any children.");
112                    }
113                } else {
114                    if (term.isUseTerm()) {
115                        termString.append(" exactly.");
116                    }
117                }
118
119                return termString.append("'").
120                    toString();
121            }).
122            collect(Collectors.joining("|", "[", "]")));
123        return sb.toString();
124    }
125
126    /**
127     * Creates a string representation of a mapping rule.
128     * @param rule the cv mapping rule
129     * @return the string representation
130     * @see niceToString for a nicer string intended for humans
131     */
132    public static String toString(CvMappingRule rule) {
133        StringBuilder sb = new StringBuilder();
134        return sb.append("Rule{").
135            append("id='").
136            append(rule.getId()).
137            append("', ").
138            append("name='").
139            append(rule.getName()).
140            append("', ").
141            append("cvElementPath='").
142            append(rule.getCvElementPath()).
143            append("', ").
144            append("scopePath='").
145            append(rule.getScopePath()).
146            append("', ").
147            append("requirementLevel='").
148            append(rule.getRequirementLevel()).
149            append("', ").
150            append("combinationLogic='").
151            append(rule.getCvTermsCombinationLogic()).
152            append("', ").
153            append("terms='").
154            append(
155                toString(rule.getCvTerm())
156            ).
157            append("'}").
158            toString();
159    }
160
161    public static String toString(List<CvTerm> terms) {
162        StringBuilder sb = new StringBuilder();
163        terms.forEach((term) ->
164        {
165            sb.append("Term{").
166                append("cv='").
167                append(term.getCvIdentifierRef().
168                    getCvIdentifier()).
169                append("', ").
170                append("accession='").
171                append(term.getTermAccession()).
172                append("', ").
173                append("allowChildren='").
174                append(term.isAllowChildren()).
175                append("', ").
176                append("repeatable='").
177                append(term.isIsRepeatable()).
178                append("', ").
179                append("useTerm='").
180                append(term.isUseTerm()).
181                append("', ").
182                append("useTermName='").
183                append(term.isUseTermName()).
184                append("'}");
185        });
186        return sb.toString();
187    }
188
189    public static boolean isEqualTo(Term term, Parameter param) {
190        if (param.getCvLabel().
191            equals(term.getOntologyPrefix())) {
192            if (param.getCvAccession().
193                equals(term.getOboId().
194                    getIdentifier())) {
195                if (param.getName().
196                    equals(term.getLabel())) {
197                    return true;
198                }
199            }
200        }
201        return false;
202    }
203
204    public static Parameter asParameter(Term term) {
205        return new Parameter().cvLabel(term.getOntologyPrefix()).
206            cvAccession(term.getOboId().
207                getIdentifier()).
208            name(term.getLabel());
209    }
210
211    public static boolean isEqualTo(Parameter one, Parameter two) {
212        if (one.getCvLabel().
213            toUpperCase().
214            equals(two.getCvLabel().
215                toUpperCase())) {
216            if (one.getCvAccession().
217                toUpperCase().
218                equals(two.getCvAccession().
219                    toUpperCase())) {
220                if (one.getName() != null && two.getName() != null) {
221                    return one.getName().
222                        toUpperCase().
223                        equals(two.getName().
224                            toUpperCase());
225                } else { // equal if one or both names are null
226                    return true;
227                }
228            } else {
229                return false;
230            }
231
232        } else {
233            return false;
234        }
235    }
236
237    public static Parameter asParameter(CvTerm term) {
238        return new Parameter().cvAccession(term.getTermAccession()).
239            cvLabel(term.getCvIdentifierRef().
240                getCvIdentifier()).
241            name(term.getTermName());
242    }
243}