/*
*
* JBoss, Home of Professional Open Source.
* Copyright 2013, Red Hat, Inc., and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
* /
*/
package org.jboss.as.security;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ALLOWED;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.CODE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.MIN_LENGTH;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.NILLABLE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OP_ADDR;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TYPE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE_TYPE;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import org.jboss.as.controller.ListAttributeDefinition;
import org.jboss.as.controller.ModelVersion;
import org.jboss.as.controller.OperationContext;
import org.jboss.as.controller.OperationFailedException;
import org.jboss.as.controller.OperationStepHandler;
import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.PathElement;
import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.as.controller.operations.validation.EnumValidator;
import org.jboss.as.controller.operations.validation.ModelTypeValidator;
import org.jboss.as.controller.operations.validation.ParameterValidator;
import org.jboss.as.controller.operations.validation.ParametersOfValidator;
import org.jboss.as.controller.operations.validation.ParametersValidator;
import org.jboss.as.controller.operations.validation.StringLengthValidator;
import org.jboss.as.controller.registry.Resource;
import org.jboss.as.security.logging.SecurityLogger;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.ModelType;
import org.jboss.dmr.Property;
/**
* In this class there are all legacy attributes and code to enable backward compatibility with them
*
* @author <a href="mailto:tomaz.cerar@redhat.com">Tomaz Cerar</a> (c) 2012 Red Hat Inc.
*/
class LegacySupport {
private LegacySupport() {
}
/**
* @author Jason T. Greene
*/
public static class JASPIAuthenticationModulesAttributeDefinition extends ListAttributeDefinition {
private static final ParameterValidator validator;
static {
final ParametersValidator delegate = new ParametersValidator();
delegate.registerValidator(CODE, new StringLengthValidator(1));
delegate.registerValidator(Constants.FLAG, new EnumValidator<ModuleFlag>(ModuleFlag.class, true, false));
delegate.registerValidator(Constants.MODULE, new StringLengthValidator(1, true));
delegate.registerValidator(Constants.MODULE_OPTIONS, new ModelTypeValidator(ModelType.OBJECT, true));
delegate.registerValidator(Constants.LOGIN_MODULE_STACK_REF, new StringLengthValidator(1, true));
validator = new ParametersOfValidator(delegate);
}
public JASPIAuthenticationModulesAttributeDefinition() {
super(LegacySupportListAttributeBuilder.of(Constants.AUTH_MODULES, Constants.AUTH_MODULE, validator));
}
@Override
protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
// This method being used indicates a misuse of this class
throw SecurityLogger.ROOT_LOGGER.unsupportedOperationExceptionUseResourceDesc();
}
@Override
protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, CODE));
valueType.get(Constants.FLAG, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.FLAG));
valueType.get(Constants.MODULE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.MODULE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.MODULE_OPTIONS));
valueType.get(Constants.LOGIN_MODULE_STACK_REF, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.LOGIN_MODULE_STACK_REF));
}
@Override
protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, CODE));
valueType.get(Constants.FLAG, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.FLAG));
valueType.get(Constants.MODULE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.MODULE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.MODULE_OPTIONS));
valueType.get(Constants.LOGIN_MODULE_STACK_REF, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.LOGIN_MODULE_STACK_REF));
}
@Override
public void marshallAsElement(ModelNode resourceModel, final boolean marshalDefault, XMLStreamWriter writer) throws XMLStreamException {
throw SecurityLogger.ROOT_LOGGER.unsupportedOperation();
}
private ModelNode getNoTextValueTypeDescription(final ModelNode parent) {
final ModelNode valueType = parent.get(VALUE_TYPE);
final ModelNode code = valueType.get(CODE);
code.get(DESCRIPTION); // placeholder
code.get(TYPE).set(ModelType.STRING);
code.get(NILLABLE).set(false);
code.get(MIN_LENGTH).set(1);
final ModelNode flag = valueType.get(Constants.FLAG);
flag.get(DESCRIPTION); // placeholder
flag.get(TYPE).set(ModelType.STRING);
flag.get(NILLABLE).set(true);
for (ModuleFlag value : ModuleFlag.values()) { flag.get(ALLOWED).add(value.toString()); }
final ModelNode module = valueType.get(Constants.MODULE);
module.get(TYPE).set(ModelType.STRING);
module.get(NILLABLE).set(true);
final ModelNode moduleOptions = valueType.get(Constants.MODULE_OPTIONS);
moduleOptions.get(DESCRIPTION); // placeholder
moduleOptions.get(TYPE).set(ModelType.OBJECT);
moduleOptions.get(VALUE_TYPE).set(ModelType.STRING);
moduleOptions.get(NILLABLE).set(true);
final ModelNode ref = valueType.get(Constants.LOGIN_MODULE_STACK_REF);
ref.get(DESCRIPTION); // placeholder
ref.get(TYPE).set(ModelType.STRING);
ref.get(NILLABLE).set(true);
ref.get(MIN_LENGTH).set(1);
return valueType;
}
}
/**
* @author Jason T. Greene
*/
public static class LoginModulesAttributeDefinition extends ListAttributeDefinition {
public static final ParameterValidator validator;
static {
final ParametersValidator delegate = new ParametersValidator();
delegate.registerValidator(CODE, new StringLengthValidator(1));
delegate.registerValidator(Constants.FLAG, new EnumValidator<ModuleFlag>(ModuleFlag.class, false, false));
delegate.registerValidator(Constants.MODULE, new StringLengthValidator(1, true));
delegate.registerValidator(Constants.MODULE_OPTIONS, new ModelTypeValidator(ModelType.OBJECT, true));
validator = new ParametersOfValidator(delegate);
}
public LoginModulesAttributeDefinition(String name, String xmlName) {
super(LegacySupportListAttributeBuilder.of(name, xmlName, validator).setDeprecated(ModelVersion.create(1, 2, 0)));
}
@Override
protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
// This method being used indicates a misuse of this class
throw SecurityLogger.ROOT_LOGGER.unsupportedOperationExceptionUseResourceDesc();
}
@Override
protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, CODE));
valueType.get(Constants.FLAG, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.FLAG));
valueType.get(Constants.MODULE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.MODULE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.MODULE_OPTIONS));
}
@Override
protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, CODE));
valueType.get(Constants.FLAG, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.FLAG));
valueType.get(Constants.MODULE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.MODULE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.MODULE_OPTIONS));
}
@Override
public void marshallAsElement(ModelNode resourceModel, final boolean marshalDefault, XMLStreamWriter writer) throws XMLStreamException {
throw SecurityLogger.ROOT_LOGGER.unsupportedOperation();
}
private ModelNode getNoTextValueTypeDescription(final ModelNode parent) {
final ModelNode valueType = parent.get(VALUE_TYPE);
final ModelNode code = valueType.get(CODE);
code.get(DESCRIPTION); // placeholder
code.get(TYPE).set(ModelType.STRING);
code.get(NILLABLE).set(false);
code.get(MIN_LENGTH).set(1);
final ModelNode flag = valueType.get(Constants.FLAG);
flag.get(DESCRIPTION); // placeholder
flag.get(TYPE).set(ModelType.STRING);
flag.get(NILLABLE).set(false);
for (ModuleFlag value : ModuleFlag.values()) { flag.get(ALLOWED).add(value.toString()); }
final ModelNode module = valueType.get(Constants.MODULE);
module.get(TYPE).set(ModelType.STRING);
module.get(NILLABLE).set(true);
final ModelNode moduleOptions = valueType.get(Constants.MODULE_OPTIONS);
moduleOptions.get(DESCRIPTION); // placeholder
moduleOptions.get(TYPE).set(ModelType.OBJECT);
moduleOptions.get(VALUE_TYPE).set(ModelType.STRING);
moduleOptions.get(NILLABLE).set(true);
return valueType;
}
}
/**
* @author Jason T. Greene
*/
public static class MappingModulesAttributeDefinition extends ListAttributeDefinition {
private static final ParameterValidator validator;
static {
final ParametersValidator delegate = new ParametersValidator();
delegate.registerValidator(CODE, new StringLengthValidator(1));
delegate.registerValidator(Constants.TYPE, new StringLengthValidator(1));
delegate.registerValidator(Constants.MODULE, new StringLengthValidator(1, true));
delegate.registerValidator(Constants.MODULE_OPTIONS, new ModelTypeValidator(ModelType.OBJECT, true));
validator = new ParametersOfValidator(delegate);
}
public MappingModulesAttributeDefinition() {
super(LegacySupportListAttributeBuilder.of(Constants.MAPPING_MODULES, Constants.MAPPING_MODULE, validator)
.setDeprecated(ModelVersion.create(1, 2, 0))
);
}
@Override
protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
// This method being used indicates a misuse of this class
throw SecurityLogger.ROOT_LOGGER.unsupportedOperationExceptionUseResourceDesc();
}
@Override
protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, CODE));
valueType.get(Constants.TYPE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.TYPE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.MODULE_OPTIONS));
}
@Override
protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, CODE));
valueType.get(Constants.TYPE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.TYPE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.MODULE_OPTIONS));
}
@Override
public void marshallAsElement(ModelNode resourceModel, final boolean marshalDefault, XMLStreamWriter writer) throws XMLStreamException {
throw SecurityLogger.ROOT_LOGGER.unsupportedOperation();
}
private ModelNode getNoTextValueTypeDescription(final ModelNode parent) {
final ModelNode valueType = parent.get(VALUE_TYPE);
final ModelNode code = valueType.get(CODE);
code.get(DESCRIPTION); // placeholder
code.get(TYPE).set(ModelType.STRING);
code.get(NILLABLE).set(false);
code.get(MIN_LENGTH).set(1);
final ModelNode flag = valueType.get(Constants.TYPE);
flag.get(DESCRIPTION); // placeholder
flag.get(TYPE).set(ModelType.STRING);
flag.get(NILLABLE).set(false);
final ModelNode moduleOptions = valueType.get(Constants.MODULE_OPTIONS);
moduleOptions.get(DESCRIPTION); // placeholder
moduleOptions.get(TYPE).set(ModelType.OBJECT);
moduleOptions.get(VALUE_TYPE).set(ModelType.STRING);
moduleOptions.get(NILLABLE).set(true);
return valueType;
}
}
/**
* @author Jason T. Greene
*/
public static class ProviderModulesAttributeDefinition extends ListAttributeDefinition {
public static final ParameterValidator validator;
static {
final ParametersValidator delegate = new ParametersValidator();
delegate.registerValidator(CODE, new StringLengthValidator(1));
delegate.registerValidator(Constants.MODULE_OPTIONS, new ModelTypeValidator(ModelType.OBJECT, true));
validator = new ParametersOfValidator(delegate);
}
public ProviderModulesAttributeDefinition(String name, String xmlName) {
super(LegacySupportListAttributeBuilder.of(name, xmlName, validator)
.setDeprecated(ModelVersion.create(1, 2, 0))
);
}
@Override
protected void addValueTypeDescription(ModelNode node, ResourceBundle bundle) {
// This method being used indicates a misuse of this class
throw SecurityLogger.ROOT_LOGGER.unsupportedOperationExceptionUseResourceDesc();
}
@Override
protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, CODE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getResourceAttributeValueTypeDescription(getName(), locale, bundle, Constants.MODULE_OPTIONS));
}
@Override
protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
final ModelNode valueType = getNoTextValueTypeDescription(node);
valueType.get(CODE, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, CODE));
valueType.get(Constants.MODULE_OPTIONS, DESCRIPTION).set(resolver.getOperationParameterValueTypeDescription(operationName, getName(), locale, bundle, Constants.MODULE_OPTIONS));
}
@Override
public void marshallAsElement(ModelNode resourceModel, final boolean marshalDefault, XMLStreamWriter writer) throws XMLStreamException {
throw SecurityLogger.ROOT_LOGGER.unsupportedOperation();
}
private ModelNode getNoTextValueTypeDescription(final ModelNode parent) {
final ModelNode valueType = parent.get(VALUE_TYPE);
final ModelNode code = valueType.get(CODE);
code.get(DESCRIPTION); // placeholder
code.get(TYPE).set(ModelType.STRING);
code.get(NILLABLE).set(false);
code.get(MIN_LENGTH).set(1);
final ModelNode moduleOptions = valueType.get(Constants.MODULE_OPTIONS);
moduleOptions.get(DESCRIPTION); // placeholder
moduleOptions.get(TYPE).set(ModelType.OBJECT);
moduleOptions.get(VALUE_TYPE).set(ModelType.STRING);
moduleOptions.get(NILLABLE).set(true);
return valueType;
}
}
/*
* handlers
*/
static class LegacyModulesAttributeReader implements OperationStepHandler {
private String newKeyName;
LegacyModulesAttributeReader(String newKeyName) {
this.newKeyName = newKeyName;
}
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
Resource resource = context.readResource(PathAddress.EMPTY_ADDRESS);
ModelNode authModules = Resource.Tools.readModel(resource).get(newKeyName);
ModelNode result = new ModelNode();
if (authModules.isDefined()) {
List<Property> loginModules = authModules.asPropertyList();
for (Property p : loginModules) {
result.add(p.getValue());
}
}
context.getResult().set(result);
}
}
static class LegacyModulesAttributeWriter implements OperationStepHandler {
private String newKeyName;
LegacyModulesAttributeWriter(String newKeyName) {
this.newKeyName = newKeyName;
}
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
Resource existing = context.readResource(PathAddress.EMPTY_ADDRESS);
OperationStepHandler addHandler = context.getResourceRegistration().getSubModel(PathAddress.EMPTY_ADDRESS.append(newKeyName)).getOperationHandler(PathAddress.EMPTY_ADDRESS, "add");
ModelNode value = operation.get(VALUE);
if (value.isDefined()) {
List<ModelNode> modules = new ArrayList<ModelNode>(value.asList());
Collections.reverse(modules); //need to reverse it to make sure they are added in proper order
for (ModelNode module : modules) {
ModelNode addModuleOp = module.clone();
String code = addModuleOp.get(Constants.CODE).asString();
PathElement relativePath = PathElement.pathElement(newKeyName, code);
PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR)).append(relativePath);
addModuleOp.get(OP_ADDR).set(address.toModelNode());
addModuleOp.get(OP).set(ADD);
context.addStep(new ModelNode(), addModuleOp, addHandler, OperationContext.Stage.MODEL, true);
}
}
//remove on the end to make sure it is executed first
for (Resource.ResourceEntry entry : existing.getChildren(newKeyName)) {
PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR)).append(entry.getPathElement());
ModelNode removeModuleOp = Util.createRemoveOperation(address);
context.addStep(new ModelNode(), removeModuleOp, new SecurityDomainReloadRemoveHandler(), OperationContext.Stage.MODEL, true);
}
}
}
static class LegacyModulesConverter implements OperationStepHandler {
private String newKeyName;
private ListAttributeDefinition oldAttribute;
LegacyModulesConverter(String newKeyName, ListAttributeDefinition oldAttribute) {
this.newKeyName = newKeyName;
this.oldAttribute = oldAttribute;
}
/*public ModelNode convertOperationAddress(ModelNode op){
PathAddress address = PathAddress.pathAddress(op.get(ModelDescriptionConstants.OP_ADDR));
op.get(ModelDescriptionConstants.OP_ADDR).set()
}*/
@Override
public void execute(OperationContext context, ModelNode operation) throws OperationFailedException {
Resource existing = context.readResource(PathAddress.EMPTY_ADDRESS);
OperationStepHandler addHandler = context.getResourceRegistration().getSubModel(PathAddress.EMPTY_ADDRESS.append(newKeyName)).getOperationHandler(PathAddress.EMPTY_ADDRESS, "add");
oldAttribute.validateOperation(operation);
List<ModelNode> modules = new ArrayList<ModelNode>(operation.get(oldAttribute.getName()).asList());
Collections.reverse(modules); //need to reverse it to make sure they are added in proper order
for (ModelNode module : modules) {
ModelNode addModuleOp = module.clone();
String code = addModuleOp.get(Constants.CODE).asString();
PathElement relativePath = PathElement.pathElement(newKeyName, code);
PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR)).append(relativePath);
addModuleOp.get(OP_ADDR).set(address.toModelNode());
addModuleOp.get(OP).set(ADD);
context.addStep(new ModelNode(), addModuleOp, addHandler, OperationContext.Stage.MODEL, true);
}
//remove on the end to make sure it is executed first
for (Resource.ResourceEntry entry : existing.getChildren(newKeyName)) {
PathAddress address = PathAddress.pathAddress(operation.get(OP_ADDR)).append(entry.getPathElement());
ModelNode removeModuleOp = Util.createRemoveOperation(address);
context.addStep(new ModelNode(), removeModuleOp, new SecurityDomainReloadRemoveHandler(), OperationContext.Stage.MODEL, true);
}
}
}
private static class LegacySupportListAttributeBuilder
extends ListAttributeDefinition.Builder<LegacySupportListAttributeBuilder, ListAttributeDefinition> {
private static LegacySupportListAttributeBuilder of(String attributeName, String xmlName,
ParameterValidator elementValidator) {
return new LegacySupportListAttributeBuilder(attributeName)
.setXmlName(xmlName)
.setElementValidator(elementValidator)
.setRequired(false)
.setMinSize(1)
.setMaxSize(Integer.MAX_VALUE)
.setDeprecated(ModelVersion.create(1, 2))
.setRestartAllServices();
}
private LegacySupportListAttributeBuilder(String attributeName) {
super(attributeName);
}
@Override
public ListAttributeDefinition build() {
// This should not be called. We only use this class to carry properties to the AD constructors
throw new UnsupportedOperationException();
}
}
}