001/*
002 * Portions of this software was developed by employees of the National Institute
003 * of Standards and Technology (NIST), an agency of the Federal Government and is
004 * being made available as a public service. Pursuant to title 17 United States
005 * Code Section 105, works of NIST employees are not subject to copyright
006 * protection in the United States. This software may be subject to foreign
007 * copyright. Permission in the United States and in foreign countries, to the
008 * extent that NIST may hold copyright, to use, copy, modify, create derivative
009 * works, and distribute this software and its documentation without fee is hereby
010 * granted on a non-exclusive basis, provided that this notice and disclaimer
011 * of warranty appears in all copies.
012 *
013 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
014 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
015 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
017 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
018 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
019 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
020 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
021 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
022 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
023 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
024 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
025 */
026
027package gov.nist.secauto.metaschema.core.datatype.markup.flexmark;
028
029import com.vladsch.flexmark.parser.ListOptions;
030
031import gov.nist.secauto.metaschema.core.util.CollectionUtil;
032import gov.nist.secauto.metaschema.core.util.ObjectUtils;
033
034import org.codehaus.stax2.evt.XMLEventFactory2;
035
036import java.util.List;
037import java.util.Map;
038import java.util.Objects;
039import java.util.stream.Collectors;
040
041import javax.xml.namespace.QName;
042import javax.xml.stream.XMLEventWriter;
043import javax.xml.stream.XMLStreamException;
044import javax.xml.stream.events.Attribute;
045import javax.xml.stream.events.EndElement;
046import javax.xml.stream.events.StartElement;
047
048import edu.umd.cs.findbugs.annotations.NonNull;
049
050public class MarkupXmlEventWriter
051    extends AbstractMarkupWriter<XMLEventWriter, XMLStreamException> {
052
053  @NonNull
054  protected final XMLEventFactory2 eventFactory;
055
056  public MarkupXmlEventWriter(
057      @NonNull String namespace,
058      @NonNull ListOptions listOptions,
059      @NonNull XMLEventWriter writer,
060      @NonNull XMLEventFactory2 eventFactory) {
061    super(namespace, listOptions, writer);
062    this.eventFactory = Objects.requireNonNull(eventFactory, "eventFactory");
063  }
064
065  @NonNull
066  protected XMLEventFactory2 getEventFactory() {
067    return eventFactory;
068  }
069
070  @NonNull
071  protected List<Attribute> handleAttributes(@NonNull Map<String, String> attributes) {
072    List<Attribute> attrs;
073    if (attributes.isEmpty()) {
074      attrs = CollectionUtil.emptyList();
075    } else {
076      attrs = ObjectUtils.notNull(attributes.entrySet().stream()
077          .map((entry) -> eventFactory.createAttribute(entry.getKey(), entry.getValue()))
078          .collect(Collectors.toList()));
079    }
080    return attrs;
081  }
082
083  @Override
084  public void writeEmptyElement(QName qname, Map<String, String> attributes) throws XMLStreamException {
085    List<Attribute> attrs = handleAttributes(attributes);
086    StartElement start = eventFactory.createStartElement(qname, attrs.isEmpty() ? null : attrs.iterator(), null);
087
088    XMLEventWriter stream = getStream();
089    stream.add(start);
090
091    EndElement end = eventFactory.createEndElement(qname, null);
092    stream.add(end);
093  }
094
095  @Override
096  public void writeElementStart(QName qname, Map<String, String> attributes) throws XMLStreamException {
097    List<Attribute> attrs = handleAttributes(attributes);
098    StartElement start = eventFactory.createStartElement(qname, attrs.isEmpty() ? null : attrs.iterator(), null);
099    getStream().add(start);
100  }
101
102  @Override
103  public void writeElementEnd(QName qname) throws XMLStreamException {
104    EndElement end = eventFactory.createEndElement(qname, null);
105    getStream().add(end);
106  }
107
108  @Override
109  public void writeText(CharSequence text) throws XMLStreamException {
110    getStream().add(eventFactory.createCharacters(text.toString()));
111  }
112
113  @Override
114  protected void writeHtmlEntityInternal(String entityText) throws XMLStreamException {
115    getStream().add(eventFactory.createEntityReference(entityText, null));
116  }
117
118  @Override
119  protected void writeComment(CharSequence text) throws XMLStreamException {
120    getStream().add(eventFactory.createComment(text.toString()));
121  }
122}