
org.xmlet.xsdparser.xsdelements.XsdExtension Maven / Gradle / Ivy
package org.xmlet.xsdparser.xsdelements;
import org.xmlet.xsdparser.core.XsdParserCore;
import org.xmlet.xsdparser.core.utils.ConfigEntryData;
import org.xmlet.xsdparser.core.utils.ParseData;
import org.xmlet.xsdparser.xsdelements.elementswrapper.NamedConcreteElement;
import org.xmlet.xsdparser.xsdelements.elementswrapper.ReferenceBase;
import org.xmlet.xsdparser.xsdelements.elementswrapper.UnsolvedReference;
import org.xmlet.xsdparser.xsdelements.exceptions.ParsingException;
import org.xmlet.xsdparser.xsdelements.visitors.XsdAbstractElementVisitor;
import org.xmlet.xsdparser.xsdelements.visitors.XsdExtensionVisitor;
import javax.validation.constraints.NotNull;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.xmlet.xsdparser.core.XsdParserCore.getParseMappers;
/**
* A class representing the xsd:extension element.
*
* @see xsd:extension description and usage at w3c
*/
public class XsdExtension extends XsdAnnotatedElements {
public static final String XSD_TAG = "xsd:extension";
public static final String XS_TAG = "xs:extension";
public static final String TAG = "extension";
/**
* The child element of the {@link XsdExtension} instance. Either a {@link XsdGroup}, {@link XsdAll},
* {@link XsdSequence} or a {@link XsdChoice} instance wrapped in a {@link ReferenceBase} object.
*/
private ReferenceBase childElement;
/**
* A {@link XsdElement} instance wrapped in a {@link ReferenceBase} object from which this {@link XsdExtension}
* instance extends.
*/
private ReferenceBase base;
private XsdExtension(@NotNull XsdParserCore parser, @NotNull Map attributesMap, @NotNull Function visitorFunction) {
super(parser, attributesMap, visitorFunction);
String baseValue = attributesMap.getOrDefault(BASE_TAG, null);
if (baseValue != null){
if (XsdParserCore.getXsdTypesToJava().containsKey(baseValue)){
HashMap attributes = new HashMap<>();
attributes.put(NAME_TAG, baseValue);
this.base = ReferenceBase.createFromXsd(new XsdBuiltInDataType(parser, attributes, this));
} else {
Map parseMappers = getParseMappers();
ConfigEntryData config = parseMappers.getOrDefault(XsdElement.XSD_TAG, parseMappers.getOrDefault(XsdElement.XS_TAG, null));
if (config == null){
throw new ParsingException("Invalid Parsing Configuration for XsdElement.");
}
this.base = new UnsolvedReference(baseValue, new XsdElement(this, this.parser, new HashMap<>(), config.visitorFunction));
parser.addUnsolvedReference((UnsolvedReference) this.base);
}
}
}
/**
* This method should always receive two elements, one to replace the {@link UnsolvedReference} created due to
* the value present in the base attribute and another if it has an {@link UnsolvedReference} as a child element.
* @param element A concrete element with a name that will replace the {@link UnsolvedReference} object created in the
* {@link XsdExtension} constructor. The {@link UnsolvedReference} is only replaced if there
* is a match between the {@link UnsolvedReference#ref} and the {@link NamedConcreteElement#name}.
*/
@Override
public void replaceUnsolvedElements(NamedConcreteElement element) {
super.replaceUnsolvedElements(element);
XsdNamedElements elem = element.getElement();
boolean isComplexOrSimpleType = elem instanceof XsdComplexType || elem instanceof XsdSimpleType;
if (this.base instanceof UnsolvedReference && isComplexOrSimpleType && compareReference(element, (UnsolvedReference) this.base)){
this.base = element;
}
if (this.childElement instanceof UnsolvedReference && elem instanceof XsdGroup && compareReference(element, (UnsolvedReference) this.childElement)){
this.childElement = element;
}
((XsdExtensionVisitor)visitor).replaceUnsolvedAttributes(parser, element, this);
}
@Override
public void accept(XsdAbstractElementVisitor visitorParam) {
super.accept(visitorParam);
visitorParam.visit(this);
}
/**
* Performs a copy of the current object for replacing purposes. The cloned objects are used to replace
* {@link UnsolvedReference} objects in the reference solving process.
* @param placeHolderAttributes The additional attributes to add to the clone.
* @return A copy of the object from which is called upon.
*/
@Override
public XsdExtension clone(@NotNull Map placeHolderAttributes) {
placeHolderAttributes.putAll(attributesMap);
XsdExtension elementCopy = new XsdExtension(this.parser, placeHolderAttributes, visitorFunction);
for(XsdAttribute attribute: getXsdAttributes().collect(Collectors.toList()))
{
elementCopy.visitor.visit((XsdAttribute) attribute.clone(attribute.attributesMap, elementCopy));
}
for(XsdAttributeGroup attributeGroup: getXsdAttributeGroup().collect(Collectors.toList()))
{
elementCopy.visitor.visit((XsdAttributeGroup) attributeGroup.clone(attributeGroup.attributesMap, elementCopy));
}
elementCopy.childElement = ReferenceBase.clone(parser, this.childElement, elementCopy);
elementCopy.base = this.base;
elementCopy.cloneOf = this;
elementCopy.parent = null;
return elementCopy;
}
/**
* @return Its children elements as his own.
*/
@Override
public List getElements() {
return childElement == null ? Collections.emptyList() : childElement.getElement().getElements();
}
/**
* @return Either a {@link XsdComplexType} or a {@link XsdSimpleType} from which this extension extends or null if
* the {@link XsdParserCore} wasn't able to replace the {@link UnsolvedReference} created by the base attribute value.
*/
public XsdNamedElements getBase() {
if (base instanceof NamedConcreteElement){
return ((NamedConcreteElement)base).getElement();
}
return null;
}
/**
* @return The {@link XsdComplexType} from which this extension extends or null if the {@link XsdParserCore} wasn't
* able to replace the {@link UnsolvedReference} created by the base attribute value.
*/
public XsdComplexType getBaseAsComplexType() {
if (base instanceof NamedConcreteElement){
XsdAbstractElement baseType = base.getElement();
if (baseType instanceof XsdComplexType){
return (XsdComplexType) baseType;
}
}
return null;
}
/**
* @return The {@link XsdSimpleType} from which this extension extends or null if the {@link XsdParserCore} wasn't
* able to replace the {@link UnsolvedReference} created by the base attribute value.
*/
@SuppressWarnings("unused")
public XsdSimpleType getBaseAsSimpleType() {
if (base instanceof NamedConcreteElement){
XsdAbstractElement baseType = base.getElement();
if (baseType instanceof XsdSimpleType){
return (XsdSimpleType) baseType;
}
}
return null;
}
/**
* @return The {@link XsdBuiltInDataType} from which this extension extends.
*/
@SuppressWarnings("unused")
public XsdBuiltInDataType getBaseAsBuiltInDataType() {
if (base instanceof NamedConcreteElement){
XsdAbstractElement baseType = base.getElement();
if (baseType instanceof XsdBuiltInDataType){
return (XsdBuiltInDataType) baseType;
}
}
return null;
}
public static ReferenceBase parse(@NotNull ParseData parseData){
return xsdParseSkeleton(parseData.node, new XsdExtension(parseData.parserInstance, convertNodeMap(parseData.node.getAttributes()), parseData.visitorFunction));
}
@SuppressWarnings("unused")
public Stream getXsdAttributes() {
return ((XsdExtensionVisitor)visitor).getXsdAttributes();
}
@SuppressWarnings("unused")
public Stream getXsdAttributeGroup() {
return ((XsdExtensionVisitor)visitor).getXsdAttributeGroups();
}
@SuppressWarnings("unused")
public XsdAbstractElement getXsdChildElement(){
if (childElement == null) {
return null;
}
return childElement instanceof UnsolvedReference ? null : childElement.getElement();
}
public void setChildElement(ReferenceBase childElement) {
this.childElement = childElement;
}
/**
* @return The childElement as a {@link XsdGroup} object or null if childElement isn't a {@link XsdGroup} instance.
*/
@SuppressWarnings("unused")
public XsdGroup getChildAsGroup() {
return childElement.getElement() instanceof XsdGroup ? (XsdGroup) childElement.getElement() : null;
}
/**
* @return The childElement as a {@link XsdAll} object or null if childElement isn't a {@link XsdAll} instance.
*/
@SuppressWarnings("unused")
public XsdAll getChildAsAll() {
return childrenIsMultipleElement() ? XsdMultipleElements.getChildAsdAll((XsdMultipleElements) childElement.getElement()) : null;
}
/**
* @return The childElement as a {@link XsdChoice} object or null if childElement isn't a {@link XsdChoice} instance.
*/
@SuppressWarnings("unused")
public XsdChoice getChildAsChoice() {
return childrenIsMultipleElement() ? XsdMultipleElements.getChildAsChoice((XsdMultipleElements) childElement.getElement()) : null;
}
/**
* @return The childElement as a {@link XsdSequence} object or null if childElement isn't a {@link XsdSequence} instance.
*/
@SuppressWarnings("unused")
public XsdSequence getChildAsSequence() {
return childrenIsMultipleElement() ? XsdMultipleElements.getChildAsSequence((XsdMultipleElements) childElement.getElement()) : null;
}
private boolean childrenIsMultipleElement(){
return childElement.getElement() instanceof XsdMultipleElements;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy