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.io.serialization; 017 018import com.fasterxml.jackson.core.JsonGenerator; 019import com.fasterxml.jackson.databind.SerializerProvider; 020import com.fasterxml.jackson.databind.ser.std.StdSerializer; 021import static de.isas.mztab2.io.serialization.Serializers.addIndexedLine; 022import static de.isas.mztab2.io.serialization.Serializers.addLine; 023import static de.isas.mztab2.io.serialization.Serializers.addLineWithMetadataProperty; 024import static de.isas.mztab2.io.serialization.Serializers.addLineWithParameters; 025import de.isas.mztab2.model.Assay; 026import de.isas.mztab2.model.CV; 027import de.isas.mztab2.model.Contact; 028import de.isas.mztab2.model.Database; 029import de.isas.mztab2.model.IndexedElement; 030import de.isas.mztab2.model.Instrument; 031import de.isas.mztab2.model.Metadata; 032import de.isas.mztab2.model.MsRun; 033import de.isas.mztab2.model.Parameter; 034import de.isas.mztab2.model.Publication; 035import de.isas.mztab2.model.Sample; 036import de.isas.mztab2.model.SampleProcessing; 037import de.isas.mztab2.model.Software; 038import de.isas.mztab2.model.StudyVariable; 039import de.isas.mztab2.model.Uri; 040import java.io.IOException; 041import java.util.Arrays; 042import java.util.Comparator; 043import java.util.List; 044import lombok.extern.slf4j.Slf4j; 045import uk.ac.ebi.pride.jmztab2.model.MZTabConstants; 046import uk.ac.ebi.pride.jmztab2.model.MetadataElement; 047import uk.ac.ebi.pride.jmztab2.model.MetadataProperty; 048import uk.ac.ebi.pride.jmztab2.model.Section; 049 050/** 051 * <p> 052 * MetadataSerializer class. Implements a custom, partially delegating serializer for {@link de.isas.mztab2.model.Metadata} objects 053 * based on Jackson CSV.</p> 054 * 055 * @author nilshoffmann 056 * 057 */ 058@Slf4j 059public class MetadataSerializer extends StdSerializer<Metadata> { 060 061 /** 062 * <p> 063 * Constructor for MetadataSerializer.</p> 064 */ 065 public MetadataSerializer() { 066 this(null); 067 } 068 069 /** 070 * <p> 071 * Constructor for MetadataSerializer.</p> 072 * 073 * @param t a {@link java.lang.Class} object. 074 */ 075 public MetadataSerializer(Class<Metadata> t) { 076 super(t); 077 } 078 079 /** 080 * <p> 081 * Serialize a list of Parameters for the provided metadata element.</p> 082 * 083 * @param list a {@link java.util.List} object. 084 * @param mtdElement a 085 * {@link uk.ac.ebi.pride.jmztab2.model.MetadataElement} object. 086 * @param jg a {@link com.fasterxml.jackson.core.JsonGenerator} object. 087 * @param sp a {@link com.fasterxml.jackson.databind.SerializerProvider} 088 * object. 089 * @param comparator a {@link java.util.Comparator} object. 090 * @param <T> a T object. 091 */ 092 public static <T extends Object> void serializeListWithMetadataElement( 093 List<T> list, MetadataElement mtdElement, JsonGenerator jg, 094 SerializerProvider sp, Comparator<? super T> comparator) { 095 list.stream(). 096 sorted(comparator). 097 forEach((object) -> 098 { 099 if (object != null) { 100 addIndexedLine(jg, sp, Section.Metadata.getPrefix(), 101 mtdElement.getName() + "[" + IndexedElement.of(object).getId() + "]", 102 object); 103 } else { 104 throw new NullPointerException( 105 "Object in list for metadata element " + mtdElement. 106 getName() + " must not be null!"); 107 } 108 }); 109 } 110 111 /** 112 * <p> 113 * serializeList.</p> 114 * 115 * @param list a {@link java.util.List} object. 116 * @param jg a {@link com.fasterxml.jackson.core.JsonGenerator} object. 117 * @param sp a {@link com.fasterxml.jackson.databind.SerializerProvider} 118 * object. 119 * @param comparator a {@link java.util.Comparator} object. 120 * @param <T> a T object. 121 */ 122 public static <T> void serializeList(List<T> list, JsonGenerator jg, 123 SerializerProvider sp, Comparator<? super T> comparator) { 124 list.stream(). 125 sorted(comparator). 126 forEach((object) -> 127 { 128 serializeObject(object, jg, sp); 129 }); 130 } 131 132 /** 133 * <p> 134 * serializeObject.</p> 135 * 136 * @param object a {@link java.lang.Object} object. 137 * @param jg a {@link com.fasterxml.jackson.core.JsonGenerator} object. 138 * @param sp a {@link com.fasterxml.jackson.databind.SerializerProvider} 139 * object. 140 */ 141 public static void serializeObject(Object object, JsonGenerator jg, 142 SerializerProvider sp) { 143 try { 144 145 log.debug( 146 "Serializing element " + Serializers. 147 getElementName(object). 148 orElse("undefined")); 149 sp.findValueSerializer(object.getClass()). 150 serialize(object, jg, sp); 151 } catch (IOException ex) { 152 log.error("Caught IO exception while trying to serialize "+object, ex); 153 } 154 } 155 156 /** 157 * {@inheritDoc} 158 */ 159 @Override 160 public void serialize(Metadata t, JsonGenerator jg, SerializerProvider sp) throws IOException { 161 if (t != null) { 162 String prefix = t.getPrefix(). 163 name(); 164 if(t.getMzTabVersion()==null || t.getMzTabVersion().isEmpty()) { 165 t.setMzTabVersion(MZTabConstants.VERSION_MZTAB_M); 166 } 167 addLine(jg, prefix, Metadata.Properties.mzTabVersion.getPropertyName(), t.getMzTabVersion()); 168 addLine(jg, prefix, Metadata.Properties.mzTabID.getPropertyName(), t. 169 getMzTabID()); 170 addLine(jg, prefix, Metadata.Properties.title.getPropertyName(), t. 171 getTitle()); 172 addLine(jg, prefix, Metadata.Properties.description.getPropertyName(), t. 173 getDescription()); 174 //contacts 175 if (t.getContact() != null) { 176 serializeList(t.getContact(), jg, sp, Comparator.comparing( 177 Contact::getId, 178 Comparator.nullsFirst(Comparator.naturalOrder()) 179 )); 180 } else { 181 182 log.debug( "Contacts are null!"); 183 } 184 //publications 185 if (t.getPublication() != null) { 186 serializeList(t.getPublication(), jg, sp, Comparator.comparing( 187 Publication::getId, 188 Comparator.nullsFirst(Comparator.naturalOrder()) 189 )); 190 } else { 191 192 log.debug( "Publications are null!"); 193 } 194 //file uri 195 if (t.getUri() != null) { 196 serializeListWithMetadataElement(t.getUri(), 197 MetadataElement.URI, jg, sp, Comparator.comparing( 198 Uri::getId, 199 Comparator.nullsFirst(Comparator.naturalOrder()))); 200 } else { 201 202 log.debug( "URI is null!"); 203 } 204 //external study uri 205 if (t.getExternalStudyUri() != null) { 206 serializeListWithMetadataElement(t.getExternalStudyUri(), 207 MetadataElement.EXTERNAL_STUDY_URI, jg, sp, Comparator. 208 comparing( 209 Uri::getId, 210 Comparator.nullsFirst(Comparator.naturalOrder()))); 211 } else { 212 213 log.debug( "External Study URI is null!"); 214 } 215 //instruments 216 if (t.getInstrument() != null) { 217 serializeList( 218 t.getInstrument(), jg, sp, Comparator.comparing( 219 Instrument::getId, 220 Comparator.nullsFirst(Comparator.naturalOrder()) 221 )); 222 } else { 223 224 log.debug( "Instruments are null!"); 225 } 226 //quantification method 227 if (t.getQuantificationMethod() != null) { 228 addLineWithParameters(jg, prefix, "quantification_method", 229 Arrays.asList(t.getQuantificationMethod())); 230 } else { 231 232 log.debug( "Quantification method is null!"); 233 } 234 //sample 235 if (t.getSample() != null) { 236 serializeList( 237 t.getSample(), jg, sp, Comparator.comparing(Sample::getId, 238 Comparator.nullsFirst(Comparator.naturalOrder()) 239 )); 240 } else { 241 242 log.debug( "Samples are null!"); 243 } 244 //sample processing 245 if (t.getSampleProcessing() != null) { 246 serializeList( 247 t.getSampleProcessing(), jg, sp, Comparator.comparing( 248 SampleProcessing::getId, 249 Comparator.nullsFirst(Comparator.naturalOrder()) 250 )); 251 } else { 252 253 log.debug( "Sample processing is null!"); 254 } 255 //software 256 if (t.getSoftware() != null) { 257 serializeList( 258 t.getSoftware(), jg, sp, Comparator.comparing( 259 Software::getId, 260 Comparator.nullsFirst(Comparator.naturalOrder()) 261 )); 262 } else { 263 264 log.debug( "Software is null!"); 265 } 266 //derivatization agent 267 if (t.getDerivatizationAgent() != null) { 268 serializeListWithMetadataElement(t.getDerivatizationAgent(), 269 MetadataElement.DERIVATIZATION_AGENT, jg, sp, Comparator. 270 comparing( 271 Parameter::getId, 272 Comparator.nullsFirst(Comparator.naturalOrder()) 273 )); 274 } else { 275 276 log.debug( "Derivatization agent is null!"); 277 } 278 //ms run 279 if (t.getMsRun() != null) { 280 serializeList(t.getMsRun(), jg, sp, Comparator.comparing( 281 MsRun::getId, 282 Comparator.nullsFirst(Comparator.naturalOrder()) 283 )); 284 } else { 285 286 log.debug( "MS runs are null!"); 287 } 288 //assay 289 if (t.getAssay() != null) { 290 serializeList(t.getAssay(), jg, sp, Comparator.comparing( 291 Assay::getId, 292 Comparator.nullsFirst(Comparator.naturalOrder()) 293 )); 294 } else { 295 296 log.debug( "Assays are null!"); 297 } 298 //study variable 299 if (t.getStudyVariable() != null) { 300 serializeList( 301 t.getStudyVariable(), jg, sp, Comparator.comparing( 302 StudyVariable::getId, 303 Comparator.nullsFirst(Comparator.naturalOrder()) 304 )); 305 } else { 306 307 log.debug( "Study Variable is null!"); 308 } 309 //custom 310 if (t.getCustom() != null) { 311 serializeListWithMetadataElement(t.getCustom(), 312 MetadataElement.CUSTOM, jg, sp, Comparator.comparing( 313 Parameter::getId, Comparator.nullsFirst(Comparator. 314 naturalOrder()))); 315 } else { 316 317 log.debug( "Custom is null!"); 318 } 319 //cv 320 if (t.getCv() != null) { 321 serializeList(t.getCv(), jg, sp, Comparator.comparing( 322 CV::getId, 323 Comparator.nullsFirst(Comparator.naturalOrder()) 324 )); 325 } else { 326 327 log.debug( "CVs are null!"); 328 } 329 //small molecule quantification unit 330 if (t.getSmallMoleculeQuantificationUnit() != null) { 331 addLineWithMetadataProperty(jg, prefix, 332 MetadataProperty.SMALL_MOLECULE_QUANTIFICATION_UNIT, 333 MetadataElement.SMALL_MOLECULE, t. 334 getSmallMoleculeQuantificationUnit()); 335 } else { 336 337 log.debug( 338 "Small molecule quantification unit is null!"); 339 } 340 //small molecule feature quantification unit 341 if (t.getSmallMoleculeFeatureQuantificationUnit() != null) { 342 addLineWithMetadataProperty(jg, prefix, 343 MetadataProperty.SMALL_MOLECULE_FEATURE_QUANTIFICATION_UNIT, 344 MetadataElement.SMALL_MOLECULE_FEATURE, t. 345 getSmallMoleculeFeatureQuantificationUnit()); 346 } else { 347 348 log.debug( 349 "Small molecule feature quantification unit is null!"); 350 } 351 //small molecule identification reliability 352 if (t.getSmallMoleculeIdentificationReliability() != null) { 353 addLineWithMetadataProperty(jg, prefix, 354 MetadataProperty.SMALL_MOLECULE_IDENTIFICATION_RELIABILITY, 355 MetadataElement.SMALL_MOLECULE, t. 356 getSmallMoleculeIdentificationReliability()); 357 } else { 358 359 log.debug( 360 "Small molecule identification reliability is null!"); 361 } 362 //database 363 if (t.getDatabase() != null) { 364 serializeList(t.getDatabase(), jg, sp, Comparator.comparing( 365 Database::getId, 366 Comparator.nullsFirst(Comparator.naturalOrder()) 367 )); 368 } else { 369 370 log.debug( "Databases are null!"); 371 } 372 if (t.getIdConfidenceMeasure() != null) { 373 serializeListWithMetadataElement(t.getIdConfidenceMeasure(), 374 MetadataElement.ID_CONFIDENCE_MEASURE, jg, sp, Comparator. 375 comparing( 376 Parameter::getId, Comparator.nullsFirst(Comparator. 377 naturalOrder()))); 378 } else { 379 380 log.debug( "Id confidence measure is null!"); 381 } 382 if (t.getColunitSmallMolecule() != null) { 383 t.getColunitSmallMolecule(). 384 forEach((colUnit) -> 385 { 386 addLine(jg, prefix, 387 MetadataElement.COLUNIT_SMALL_MOLECULE, colUnit. 388 getColumnName() + "=" + new ParameterConverter(). 389 convert(colUnit.getParam())); 390 }); 391 } else { 392 393 log.debug( "Colunit small molecule is null!"); 394 } 395 if (t.getColunitSmallMoleculeFeature() != null) { 396 t.getColunitSmallMoleculeFeature(). 397 forEach((colUnit) -> 398 { 399 addLine(jg, prefix, 400 MetadataElement.COLUNIT_SMALL_MOLECULE_FEATURE, 401 colUnit. 402 getColumnName() + "=" + new ParameterConverter(). 403 convert(colUnit.getParam())); 404 }); 405 } else { 406 407 log.debug( "Colunit small molecule feature is null!"); 408 } 409 if (t.getColunitSmallMoleculeEvidence() != null) { 410 t.getColunitSmallMoleculeEvidence(). 411 forEach((colUnit) -> 412 { 413 addLine(jg, prefix, 414 MetadataElement.COLUNIT_SMALL_MOLECULE_EVIDENCE, 415 colUnit. 416 getColumnName() + "=" + new ParameterConverter(). 417 convert(colUnit.getParam())); 418 }); 419 } else { 420 421 log.debug( "Colunit small molecule evidence is null!"); 422 } 423 } 424 } 425 426}