001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.databind.io.xml; 007 008import org.apache.logging.log4j.LogManager; 009import org.apache.logging.log4j.Logger; 010 011import java.util.HashSet; 012import java.util.Set; 013 014import javax.xml.stream.events.Attribute; 015 016import dev.metaschema.core.model.IBoundObject; 017import dev.metaschema.core.model.util.XmlEventUtil; 018import dev.metaschema.core.qname.IEnhancedQName; 019import dev.metaschema.core.util.ObjectUtils; 020import dev.metaschema.databind.io.AbstractProblemHandler; 021import dev.metaschema.databind.model.IBoundDefinitionModelComplex; 022 023/** 024 * Handles problems identified in the parsed XML. 025 * <p> 026 * The default problem handler will report unknown attributes, and provide empty 027 * collections for multi-valued model items and default values for flags and 028 * single valued fields. 029 */ 030public class DefaultXmlProblemHandler 031 extends AbstractProblemHandler 032 implements IXmlProblemHandler { 033 private static final Logger LOGGER = LogManager.getLogger(DefaultXmlProblemHandler.class); 034 035 /** 036 * Construct a new problem handler with required field validation enabled. 037 */ 038 public DefaultXmlProblemHandler() { 039 super(); 040 } 041 042 /** 043 * Construct a new problem handler with the specified validation setting. 044 * 045 * @param validateRequiredFields 046 * {@code true} to validate that required fields are present, 047 * {@code false} to skip validation 048 */ 049 public DefaultXmlProblemHandler(boolean validateRequiredFields) { 050 super(validateRequiredFields); 051 } 052 053 private static final IEnhancedQName XSI_SCHEMA_LOCATION 054 = IEnhancedQName.of("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation"); 055 private static final Set<IEnhancedQName> IGNORED_QNAMES; 056 057 static { 058 IGNORED_QNAMES = new HashSet<>(); 059 IGNORED_QNAMES.add(XSI_SCHEMA_LOCATION); 060 } 061 062 @Override 063 public boolean handleUnknownAttribute( 064 IBoundDefinitionModelComplex parentDefinition, 065 IBoundObject targetObject, 066 Attribute attribute, 067 IXmlParsingContext parsingContext) { 068 IEnhancedQName qname = IEnhancedQName.of(ObjectUtils.requireNonNull(attribute.getName())); 069 // check if warning is needed 070 if (LOGGER.isWarnEnabled() && !IGNORED_QNAMES.contains(qname)) { 071 LOGGER.atWarn().log("Skipping unrecognized attribute '{}'{}.", 072 qname, 073 XmlEventUtil.generateLocationMessage( 074 ObjectUtils.notNull(attribute.getLocation()), 075 parsingContext.getSource())); 076 } 077 // always ignore 078 return true; 079 } 080}