/*
* Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com
* The software in this package is published under the terms of the CPAL v1.0
* license, a copy of which has been included with this distribution in the
* LICENSE.txt file.
*/
package org.mule.runtime.module.extension.internal.capability.xml.schema.builder;
import static java.math.BigInteger.ONE;
import static java.math.BigInteger.ZERO;
import static java.util.Optional.empty;
import static org.mule.runtime.extension.api.util.ExtensionModelUtils.getDynamicParameters;
import static org.mule.runtime.extension.api.util.ExtensionModelUtils.getFirstImplicit;
import static org.mule.runtime.config.spring.dsl.api.xml.SchemaConstants.MAX_ONE;
import static org.mule.runtime.config.spring.dsl.api.xml.SchemaConstants.MULE_ABSTRACT_EXTENSION;
import static org.mule.runtime.config.spring.dsl.api.xml.SchemaConstants.MULE_ABSTRACT_EXTENSION_TYPE;
import static org.mule.runtime.config.spring.dsl.api.xml.SchemaConstants.MULE_EXTENSION_CONNECTION_PROVIDER_ELEMENT;
import static org.mule.runtime.config.spring.dsl.api.xml.SchemaConstants.MULE_EXTENSION_DYNAMIC_CONFIG_POLICY_ELEMENT;
import org.mule.runtime.api.meta.model.ExtensionModel;
import org.mule.runtime.api.meta.model.config.ConfigurationModel;
import org.mule.runtime.extension.api.dsl.syntax.DslElementSyntax;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.ComplexContent;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.Element;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.ExplicitGroup;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.ExtensionType;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.LocalComplexType;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.ObjectFactory;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.Schema;
import org.mule.runtime.module.extension.internal.capability.xml.schema.model.TopLevelElement;
import java.util.List;
import java.util.Optional;
/**
* Builder delegation class to generate a XSD schema that describes a {@link ConfigurationModel}
*
* @since 4.0.0
*/
final class ConfigurationSchemaDelegate {
private final ObjectFactory objectFactory = new ObjectFactory();
private final SchemaBuilder builder;
private Schema schema;
ConfigurationSchemaDelegate(SchemaBuilder builder) {
this.builder = builder;
}
void registerConfigElement(Schema schema, final ConfigurationModel configurationModel,
DslElementSyntax dslConfigElement) {
this.schema = schema;
ExtensionType config = registerExtension(dslConfigElement.getElementName());
config.getAttributeOrAttributeGroup().add(builder.createNameAttribute(true));
config.setAnnotation(builder.createDocAnnotation(configurationModel.getDescription()));
Optional<TopLevelElement> connectionElement = addConnectionProviderElement(configurationModel);
Optional<TopLevelElement> policyElement = addDynamicConfigPolicyElement(configurationModel);
if (connectionElement.isPresent() || policyElement.isPresent() || !configurationModel.getParameterGroupModels().isEmpty()) {
final ExplicitGroup sequence = new ExplicitGroup();
sequence.setMinOccurs(ZERO);
sequence.setMaxOccurs(MAX_ONE);
connectionElement.ifPresent(connection -> {
sequence.getParticle().add(objectFactory.createElement(connection));
if (builder.isRequired(connection)) {
sequence.setMinOccurs(ONE);
}
});
policyElement.ifPresent(policy -> {
sequence.getParticle().add(objectFactory.createElement(policy));
if (builder.isRequired(policy)) {
sequence.setMinOccurs(ONE);
}
});
builder.addInfrastructureParameters(config, configurationModel, sequence);
configurationModel.getParameterGroupModels().forEach(group -> {
if (!group.isShowInDsl()) {
List<TopLevelElement> parameters = builder.registerParameters(config, group.getParameterModels());
builder.addParameterToSequence(parameters, sequence);
} else {
builder.addInlineParameterGroup(group, sequence);
}
});
config.setSequence(sequence);
}
}
private ExtensionType registerExtension(String name) {
LocalComplexType complexType = new LocalComplexType();
Element extension = new TopLevelElement();
extension.setName(name);
extension.setSubstitutionGroup(MULE_ABSTRACT_EXTENSION);
extension.setComplexType(complexType);
ComplexContent complexContent = new ComplexContent();
complexType.setComplexContent(complexContent);
ExtensionType complexContentExtension = new ExtensionType();
complexContentExtension.setBase(MULE_ABSTRACT_EXTENSION_TYPE);
complexContent.setExtension(complexContentExtension);
schema.getSimpleTypeOrComplexTypeOrGroup().add(extension);
return complexContentExtension;
}
private Optional<TopLevelElement> addConnectionProviderElement(ConfigurationModel configurationModel) {
ExtensionModel extensionModel = builder.getExtensionModel();
if (!extensionModel.getConnectionProviders().isEmpty() || !configurationModel.getConnectionProviders().isEmpty()) {
TopLevelElement objectElement = new TopLevelElement();
boolean hasImplicitConnection = getFirstImplicit(extensionModel.getConnectionProviders()) != null
|| getFirstImplicit(configurationModel.getConnectionProviders()) != null;
objectElement.setMinOccurs(hasImplicitConnection ? ZERO : ONE);
objectElement.setMaxOccurs(MAX_ONE);
objectElement.setRef(MULE_EXTENSION_CONNECTION_PROVIDER_ELEMENT);
return Optional.of(objectElement);
}
return empty();
}
private Optional<TopLevelElement> addDynamicConfigPolicyElement(ConfigurationModel configurationModel) {
if (!getDynamicParameters(configurationModel).isEmpty()) {
TopLevelElement objectElement = new TopLevelElement();
objectElement.setMinOccurs(ZERO);
objectElement.setMaxOccurs("1");
objectElement.setRef(MULE_EXTENSION_DYNAMIC_CONFIG_POLICY_ELEMENT);
return Optional.of(objectElement);
}
return empty();
}
}