package com.xenoage.zong.musicxml.types;
import com.xenoage.utils.annotations.MaybeEmpty;
import com.xenoage.utils.annotations.MaybeNull;
import com.xenoage.utils.annotations.NonNull;
import com.xenoage.utils.xml.XmlReader;
import com.xenoage.utils.xml.XmlWriter;
import com.xenoage.zong.musicxml.types.choice.MxlPartListContent;
import com.xenoage.zong.musicxml.util.IncompleteMusicXML;
import com.xenoage.zong.musicxml.util.error.handler.ErrorHandler;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import static com.xenoage.utils.collections.CollectionUtils.alist;
/**
* MusicXML score-part.
*
* @author Andreas Wenger
*/
@IncompleteMusicXML(missing = "part-name-display,part-abbreviation-display,group,midi-device",
children = "score-instrument,midi-instrument")
@AllArgsConstructor @Getter @Setter
public class MxlScorePart
implements MxlPartListContent {
public static final String elemName = "score-part";
@MaybeNull private MxlIdentification identification;
@NonNull private String partName;
@MaybeNull private String partAbbreviation;
@MaybeEmpty private List<MxlScoreInstrument> scoreInstruments;
@MaybeEmpty private List<MxlMidiInstrument> midiInstruments;
@NonNull private String id;
@Override public PartListContentType getPartListContentType() {
return PartListContentType.ScorePart;
}
@NonNull public static MxlScorePart read(XmlReader reader, ErrorHandler errorHandler) {
//attributes
String id = reader.getAttributeNotNull("id");
//elements
MxlIdentification identification = null;
String partName = null;
String partAbbreviation = null;
List<MxlScoreInstrument> scoreInstruments = alist();
List<MxlMidiInstrument> midiInstruments = alist();
while (reader.openNextChildElement()) {
String n = reader.getElementName();
switch (n.charAt(0)) { //switch for performance
case 'i':
if (n.equals(MxlIdentification.elemName))
identification = MxlIdentification.read(reader);
break;
case 'm':
if (n.equals(MxlMidiInstrument.elemName))
midiInstruments.add(MxlMidiInstrument.read(reader));
break;
case 'p':
if (n.equals("part-abbreviation"))
partAbbreviation = reader.getTextNotNull();
else if (n.equals("part-name"))
partName = reader.getTextNotNull();
break;
case 's':
if (n.equals(MxlScoreInstrument.elemName))
scoreInstruments.add(MxlScoreInstrument.read(reader));
break;
}
reader.closeElement();
}
if (partName == null && errorHandler.tryFix(reader.dataException("part-name unknown")))
partName = "";
return new MxlScorePart(identification, partName, partAbbreviation, scoreInstruments,
midiInstruments, id);
}
@Override public void write(XmlWriter writer) {
writer.writeElementStart(elemName);
writer.writeAttribute("id", id);
if (identification != null)
identification.write(writer);
writer.writeElementText("part-name", partName);
writer.writeElementText("part-abbreviation", partAbbreviation);
for (MxlScoreInstrument scoreInstrument : scoreInstruments)
scoreInstrument.write(writer);
for (MxlMidiInstrument midiInstrument : midiInstruments)
midiInstrument.write(writer);
writer.writeElementEnd();
}
}