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 uk.ac.ebi.pride.jmztab2.utils.parser;
017
018import de.isas.mztab2.model.Metadata;
019import de.isas.mztab2.model.OptColumnMapping;
020import de.isas.mztab2.model.SmallMoleculeFeature;
021import java.util.Arrays;
022import java.util.List;
023import java.util.regex.Matcher;
024import java.util.regex.Pattern;
025import uk.ac.ebi.pride.jmztab2.model.AbundanceColumn;
026import uk.ac.ebi.pride.jmztab2.model.IMZTabColumn;
027import uk.ac.ebi.pride.jmztab2.model.ISmallMoleculeFeatureColumn;
028import uk.ac.ebi.pride.jmztab2.model.MZBoolean;
029import uk.ac.ebi.pride.jmztab2.model.MZTabColumnFactory;
030import uk.ac.ebi.pride.jmztab2.model.MZTabConstants;
031import uk.ac.ebi.pride.jmztab2.model.OptionColumn;
032import uk.ac.ebi.pride.jmztab2.model.SmallMoleculeFeatureColumn;
033import uk.ac.ebi.pride.jmztab2.model.SmallMoleculeFeatureColumn.Stable;
034import uk.ac.ebi.pride.jmztab2.utils.errors.FormatErrorType;
035import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabError;
036import uk.ac.ebi.pride.jmztab2.utils.errors.MZTabErrorList;
037
038/**
039 * <p>
040 * SMFLineParser class.</p>
041 *
042 * @author nilshoffmann
043 * @since 11/09/17
044 *
045 */
046public class SMFLineParser extends MZTabDataLineParser<SmallMoleculeFeature> {
047
048    private SmallMoleculeFeature smallMoleculeFeature;
049
050    /**
051     * <p>
052     * Constructor for SMFLineParser.</p>
053     *
054     * @param context a
055     * {@link uk.ac.ebi.pride.jmztab2.utils.parser.MZTabParserContext} object.
056     * @param factory a {@link uk.ac.ebi.pride.jmztab2.model.MZTabColumnFactory}
057     * object.
058     * @param positionMapping a
059     * {@link uk.ac.ebi.pride.jmztab2.utils.parser.PositionMapping} object.
060     * @param metadata a {@link de.isas.mztab2.model.Metadata} object.
061     * @param errorList a
062     * {@link uk.ac.ebi.pride.jmztab2.utils.errors.MZTabErrorList} object.
063     */
064    public SMFLineParser(MZTabParserContext context, MZTabColumnFactory factory,
065        PositionMapping positionMapping,
066        Metadata metadata, MZTabErrorList errorList) {
067        super(context, factory, positionMapping, metadata, errorList);
068    }
069
070    /**
071     * {@inheritDoc}
072     */
073    @Override
074    protected int checkData() {
075
076        IMZTabColumn column;
077        String columnName;
078        String target;
079        int physicalPosition;
080        String logicalPosition;
081        smallMoleculeFeature = new SmallMoleculeFeature();
082
083        for (physicalPosition = 1; physicalPosition < items.length; physicalPosition++) {
084            logicalPosition = positionMapping.get(physicalPosition);
085            column = factory.getColumnMapping().
086                get(logicalPosition);
087
088            if (column != null) {
089                columnName = column.getName();
090                target = items[physicalPosition];
091                if (column instanceof ISmallMoleculeFeatureColumn) {
092                    Stable stableColumn = SmallMoleculeFeatureColumn.Stable.
093                        forName(columnName);
094                    switch (stableColumn) {
095                        case ADDUCT_ION:
096                            String adductIon = checkString(column,
097                                target);
098                            checkRegexMatches(errorList, lineNumber,
099                                SmallMoleculeFeature.Properties.adductIon,
100                                MZTabConstants.REGEX_ADDUCT, Arrays.asList(
101                                    adductIon));
102                            smallMoleculeFeature.adductIon(adductIon);
103                            break;
104                        case CHARGE:
105                            smallMoleculeFeature.charge(checkInteger(column,
106                                checkData(column, target, false)));
107                            break;
108                        case EXP_MASS_TO_CHARGE:
109                            smallMoleculeFeature.expMassToCharge(
110                                checkDouble(column, checkData(column, target,
111                                    false)));
112                            break;
113                        case ISOTOPOMER:
114                            smallMoleculeFeature.isotopomer(checkParameter(
115                                column, target, true));
116                            break;
117                        case RETENTION_TIME_IN_SECONDS:
118                            smallMoleculeFeature.retentionTimeInSeconds(
119                                checkDouble(
120                                    column, target));
121                            break;
122                        case RETENTION_TIME_IN_SECONDS_END:
123                            smallMoleculeFeature.retentionTimeInSecondsEnd(
124                                checkDouble(
125                                    column, target));
126                            break;
127                        case RETENTION_TIME_IN_SECONDS_START:
128                            smallMoleculeFeature.retentionTimeInSecondsStart(
129                                checkDouble(
130                                    column, target));
131                            break;
132                        case SME_ID_REFS:
133                            smallMoleculeFeature.smeIdRefs(checkIntegerList(
134                                column, target, MZTabConstants.BAR));
135                            break;
136                        case SME_ID_REF_AMBIGUITY_CODE:
137                            smallMoleculeFeature.smeIdRefAmbiguityCode(
138                                checkInteger(
139                                    column, target));
140                            break;
141                        case SMF_ID:
142                            smallMoleculeFeature.smfId(checkInteger(
143                                column, checkData(column, target, false)));
144                            break;
145                    }
146
147                } else if (column instanceof AbundanceColumn) {
148                    if (columnName.startsWith(
149                        SmallMoleculeFeature.Properties.abundanceAssay.
150                            getPropertyName())) {
151                        smallMoleculeFeature.addAbundanceAssayItem(checkDouble(
152                            column, target));
153                    }
154                } else if (column instanceof OptionColumn) {
155                    if (columnName.startsWith(MZTabConstants.OPT_PREFIX)) {
156                        Class dataType = column.getDataType();
157                        OptColumnMapping optColMapping = new OptColumnMapping();
158                        optColMapping.identifier(columnName.substring(
159                            MZTabConstants.OPT_PREFIX.length()));
160                        if (dataType.equals(String.class)) {
161                            optColMapping.value(checkString(column, target));
162                        } else if (dataType.equals(Double.class)) {
163                            optColMapping.value(Double.toString(checkDouble(
164                                column, target)));
165                        } else if (dataType.equals(MZBoolean.class)) {
166                            optColMapping.value(Boolean.toString(checkMZBoolean(
167                                column, target).
168                                toBoolean()));
169                        }
170                        smallMoleculeFeature.addOptItem(optColMapping);
171                    }
172                }
173            }
174        }
175
176        return physicalPosition;
177    }
178
179    protected void checkRegexMatches(MZTabErrorList errorList, int lineNumber,
180        SmallMoleculeFeature.Properties elementProperty,
181        String regularExpression, List<String> elements) {
182        if (!elements.isEmpty()) {
183            Pattern p = Pattern.compile(regularExpression);
184            for (int i = 0; i < elements.size(); i++) {
185                String element = elements.get(i);
186                if (!"null".equals(element)) {
187                    Matcher m = p.matcher(element);
188                    if (!m.matches()) {
189                        errorList.add(new MZTabError(
190                            FormatErrorType.RegexMismatch,
191                            lineNumber, elementProperty.getPropertyName(),
192                            element,
193                            "" + (i + 1), regularExpression));
194                    }
195                }
196            }
197        }
198
199    }
200
201    /**
202     * {@inheritDoc}
203     */
204    @Override
205    public SmallMoleculeFeature getRecord() {
206
207        if (smallMoleculeFeature == null) {
208            smallMoleculeFeature = new SmallMoleculeFeature();//(factory, metadata);
209        }
210        return smallMoleculeFeature;
211    }
212}