PageRenderTime 138ms CodeModel.GetById 45ms app.highlight 86ms RepoModel.GetById 2ms app.codeStats 0ms

/jboss-as-7.1.1.Final/controller/src/main/java/org/jboss/as/controller/descriptions/common/InterfaceDescription.java

#
Java | 379 lines | 278 code | 43 blank | 58 comment | 18 complexity | 22aa238e64650b7f099335506f582e58 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
  1/*
  2 * JBoss, Home of Professional Open Source.
  3 * Copyright 2011, Red Hat, Inc., and individual contributors
  4 * as indicated by the @author tags. See the copyright.txt file in the
  5 * distribution for a full listing of individual contributors.
  6 *
  7 * This is free software; you can redistribute it and/or modify it
  8 * under the terms of the GNU Lesser General Public License as
  9 * published by the Free Software Foundation; either version 2.1 of
 10 * the License, or (at your option) any later version.
 11 *
 12 * This software is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 15 * Lesser General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU Lesser General Public
 18 * License along with this software; if not, write to the Free
 19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 21 */
 22package org.jboss.as.controller.descriptions.common;
 23
 24import static org.jboss.as.controller.ControllerMessages.MESSAGES;
 25import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ADD;
 26import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.ALTERNATIVES;
 27import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.DESCRIPTION;
 28import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.HEAD_COMMENT_ALLOWED;
 29import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.OPERATION_NAME;
 30import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REMOVE;
 31import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REPLY_PROPERTIES;
 32import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.REQUEST_PROPERTIES;
 33import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.TAIL_COMMENT_ALLOWED;
 34import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.VALUE_TYPE;
 35
 36import java.util.Arrays;
 37import java.util.HashSet;
 38import java.util.Locale;
 39import java.util.ResourceBundle;
 40import java.util.Set;
 41
 42import javax.xml.stream.XMLStreamException;
 43import javax.xml.stream.XMLStreamWriter;
 44
 45import org.jboss.as.controller.AttributeDefinition;
 46import org.jboss.as.controller.ListAttributeDefinition;
 47import org.jboss.as.controller.OperationFailedException;
 48import org.jboss.as.controller.SimpleAttributeDefinitionBuilder;
 49import org.jboss.as.controller.client.helpers.MeasurementUnit;
 50import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
 51import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
 52import org.jboss.as.controller.operations.validation.ModelTypeValidator;
 53import org.jboss.as.controller.operations.validation.ParameterValidator;
 54import org.jboss.as.controller.parsing.Element;
 55import org.jboss.as.controller.registry.AttributeAccess;
 56import org.jboss.dmr.ModelNode;
 57import org.jboss.dmr.ModelType;
 58
 59/**
 60 * Model descriptions for interface elements.
 61 *
 62 * @author Brian Stansberry
 63 * @author Emanuel Muckenhuber
 64 */
 65public class InterfaceDescription {
 66
 67    private static final String RESOURCE_NAME = InterfaceDescription.class.getPackage().getName() + ".LocalDescriptions";
 68
 69    public static ModelNode getNamedInterfaceDescription(final Locale locale) {
 70        final ResourceBundle bundle = getResourceBundle(locale);
 71
 72        final ModelNode root = new ModelNode();
 73        root.get(DESCRIPTION).set(bundle.getString("named_interface"));
 74        NAME.addResourceAttributeDescription(bundle, "interface", root);
 75        populateInterface(root, bundle, false);
 76        return root;
 77    }
 78
 79    public static ModelNode getSpecifiedInterfaceDescription(final Locale locale) {
 80        final ResourceBundle bundle = getResourceBundle(locale);
 81
 82        final ModelNode root = new ModelNode();
 83        root.get(DESCRIPTION).set(bundle.getString("specified_interface"));
 84        NAME.addResourceAttributeDescription(bundle, "interface", root);
 85        populateInterface(root, bundle, true);
 86        return root;
 87    }
 88
 89    private static void populateInterface(ModelNode root, ResourceBundle bundle, boolean specified) {
 90        root.get(HEAD_COMMENT_ALLOWED).set(true);
 91        root.get(TAIL_COMMENT_ALLOWED).set(false);
 92        // Add the interface criteria operation params
 93        for(final AttributeDefinition def : ROOT_ATTRIBUTES) {
 94            def.addResourceAttributeDescription(bundle, "interface", root);
 95        }
 96    }
 97
 98    public static ModelNode getNamedInterfaceAddOperation(final Locale locale) {
 99        final ResourceBundle bundle = getResourceBundle(locale);
100        final ModelNode root = new ModelNode();
101        root.get(OPERATION_NAME).set(ADD);
102        root.get(DESCRIPTION).set(bundle.getString("interface.add"));
103        // Add the interface criteria attributes
104        for(final AttributeDefinition def : ROOT_ATTRIBUTES) {
105            def.addOperationParameterDescription(bundle, "interface", root);
106        }
107        return root;
108    }
109
110    public static ModelNode getSpecifiedInterfaceAddOperation(final Locale locale) {
111        final ResourceBundle bundle = getResourceBundle(locale);
112        final ModelNode root = new ModelNode();
113        root.get(OPERATION_NAME).set(ADD);
114        root.get(DESCRIPTION).set(bundle.getString("interface.add"));
115        // Add the interface criteria attributes
116        for(final AttributeDefinition def : ROOT_ATTRIBUTES) {
117            def.addOperationParameterDescription(bundle, "interface", root);
118        }
119        return root;
120    }
121
122    public static ModelNode getInterfaceRemoveOperation(final Locale locale) {
123        final ResourceBundle bundle = getResourceBundle(locale);
124        final ModelNode root = new ModelNode();
125        root.get(OPERATION_NAME).set(REMOVE);
126        root.get(DESCRIPTION).set(bundle.getString("interface.remove"));
127        root.get(REQUEST_PROPERTIES).setEmptyObject();
128        root.get(REPLY_PROPERTIES).setEmptyObject();
129        return root;
130    }
131
132    private static ResourceBundle getResourceBundle(Locale locale) {
133        if (locale == null) {
134            locale = Locale.getDefault();
135        }
136        return ResourceBundle.getBundle(RESOURCE_NAME, locale);
137    }
138
139    /**
140     * Test whether the operation has a defined criteria attribute.
141     *
142     * @param operation the operation
143     * @return
144     */
145    public static boolean isOperationDefined(final ModelNode operation) {
146        for(final AttributeDefinition def : ROOT_ATTRIBUTES) {
147            if(operation.hasDefined(def.getName())) {
148                return true;
149            }
150        }
151        return false;
152    }
153
154    /** The any-* alternatives. */
155    private static final String[] ALTERNATIVES_ANY = new String[] { ModelDescriptionConstants.ANY_ADDRESS, ModelDescriptionConstants.ANY_IPV4_ADDRESS, ModelDescriptionConstants.ANY_IPV6_ADDRESS};
156
157    /** All other attribute names. */
158    private static final String[] OTHERS = new String[] { localName(Element.INET_ADDRESS), localName(Element.LINK_LOCAL_ADDRESS),
159            localName(Element.LOOPBACK), localName(Element.LOOPBACK_ADDRESS), localName(Element.MULTICAST), localName(Element.NIC),
160            localName(Element.NIC_MATCH), localName(Element.POINT_TO_POINT), localName(Element.PUBLIC_ADDRESS), localName(Element.SITE_LOCAL_ADDRESS),
161            localName(Element.SUBNET_MATCH), localName(Element.UP), localName(Element.VIRTUAL),
162            localName(Element.ANY), localName(Element.NOT)
163    };
164
165    public static final AttributeDefinition NAME = SimpleAttributeDefinitionBuilder.create(ModelDescriptionConstants.NAME, ModelType.STRING)
166            .build();
167
168    public static final AttributeDefinition ANY_ADDRESS = SimpleAttributeDefinitionBuilder.create(ModelDescriptionConstants.ANY_ADDRESS, ModelType.BOOLEAN)
169            .setAllowExpression(false).setAllowNull(false).setRestartAllServices()
170            .setValidator(new ModelTypeValidator(ModelType.BOOLEAN, true, true))
171            .addAlternatives(OTHERS).addAlternatives(ModelDescriptionConstants.ANY_IPV4_ADDRESS, ModelDescriptionConstants.ANY_IPV6_ADDRESS)
172            .build();
173    public static final AttributeDefinition ANY_IPV4_ADDRESS = SimpleAttributeDefinitionBuilder.create(ModelDescriptionConstants.ANY_IPV4_ADDRESS, ModelType.BOOLEAN)
174            .setAllowExpression(false).setAllowNull(false).setRestartAllServices()
175            .setValidator(new ModelTypeValidator(ModelType.BOOLEAN, true, true))
176            .addAlternatives(OTHERS).addAlternatives(ModelDescriptionConstants.ANY_ADDRESS, ModelDescriptionConstants.ANY_IPV6_ADDRESS)
177            .build();
178    public static final AttributeDefinition ANY_IPV6_ADDRESS = SimpleAttributeDefinitionBuilder.create(ModelDescriptionConstants.ANY_IPV6_ADDRESS, ModelType.BOOLEAN)
179            .setAllowExpression(false).setAllowNull(false).setRestartAllServices()
180            .setValidator(new ModelTypeValidator(ModelType.BOOLEAN, true, true))
181            .addAlternatives(OTHERS).addAlternatives(ModelDescriptionConstants.ANY_ADDRESS, ModelDescriptionConstants.ANY_IPV4_ADDRESS)
182            .build();
183    public static final AttributeDefinition INET_ADDRESS = SimpleAttributeDefinitionBuilder.create(ModelDescriptionConstants.INET_ADDRESS, ModelType.STRING)
184            .setAllowExpression(true).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
185            .build();
186    public static final AttributeDefinition LINK_LOCAL_ADDRESS = SimpleAttributeDefinitionBuilder.create(localName(Element.LINK_LOCAL_ADDRESS), ModelType.BOOLEAN)
187            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
188            .build();
189    public static final AttributeDefinition LOOPBACK = SimpleAttributeDefinitionBuilder.create(localName(Element.LOOPBACK), ModelType.BOOLEAN)
190            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
191            .build();
192    public static final AttributeDefinition LOOPBACK_ADDRESS = SimpleAttributeDefinitionBuilder.create(localName(Element.LOOPBACK_ADDRESS), ModelType.STRING)
193            .setAllowExpression(true).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
194            .build();
195    public static final AttributeDefinition NIC = SimpleAttributeDefinitionBuilder.create(localName(Element.NIC), ModelType.STRING)
196            .setAllowExpression(true).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
197            .build();
198    public static final AttributeDefinition NIC_MATCH = SimpleAttributeDefinitionBuilder.create(localName(Element.NIC_MATCH), ModelType.STRING)
199            .setAllowExpression(true).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
200            .build();
201    public static final AttributeDefinition MULTICAST = SimpleAttributeDefinitionBuilder.create(localName(Element.MULTICAST), ModelType.BOOLEAN)
202            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
203            .build();
204    public static final AttributeDefinition POINT_TO_POINT = SimpleAttributeDefinitionBuilder.create(localName(Element.POINT_TO_POINT), ModelType.BOOLEAN)
205            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
206            .build();
207    public static final AttributeDefinition PUBLIC_ADDRESS = SimpleAttributeDefinitionBuilder.create(localName(Element.PUBLIC_ADDRESS), ModelType.BOOLEAN)
208            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
209            .build();
210    public static final AttributeDefinition SITE_LOCAL_ADDRESS = SimpleAttributeDefinitionBuilder.create(localName(Element.SITE_LOCAL_ADDRESS), ModelType.BOOLEAN)
211            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
212            .build();
213    public static final AttributeDefinition SUBNET_MATCH = SimpleAttributeDefinitionBuilder.create(localName(Element.SUBNET_MATCH), ModelType.STRING)
214            .setAllowExpression(true).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
215            .build();
216    public static final AttributeDefinition UP = SimpleAttributeDefinitionBuilder.create(localName(Element.UP), ModelType.BOOLEAN)
217            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
218            .build();
219    public static final AttributeDefinition VIRTUAL = SimpleAttributeDefinitionBuilder.create(localName(Element.VIRTUAL), ModelType.BOOLEAN)
220            .setAllowExpression(false).setAllowNull(true).addAlternatives(ALTERNATIVES_ANY).setRestartAllServices()
221            .build();
222    public static final AttributeDefinition NOT = createNestedComplexType("not");
223    public static final AttributeDefinition ANY = createNestedComplexType("any");
224
225    /** The root attributes. */
226    public static final AttributeDefinition[] ROOT_ATTRIBUTES = new AttributeDefinition[] {
227
228            ANY_ADDRESS, ANY_IPV4_ADDRESS, ANY_IPV6_ADDRESS, INET_ADDRESS, LINK_LOCAL_ADDRESS,
229            LOOPBACK, LOOPBACK_ADDRESS, MULTICAST, NIC, NIC_MATCH, POINT_TO_POINT, PUBLIC_ADDRESS,
230            SITE_LOCAL_ADDRESS, SUBNET_MATCH, UP, VIRTUAL, ANY, NOT
231
232    };
233
234    /** The nested attributes for any, not. */
235    public static final AttributeDefinition[] NESTED_ATTRIBUTES = new AttributeDefinition[] {
236            INET_ADDRESS, LINK_LOCAL_ADDRESS, LOOPBACK, LOOPBACK_ADDRESS, MULTICAST, NIC,
237            NIC_MATCH, POINT_TO_POINT, PUBLIC_ADDRESS, SITE_LOCAL_ADDRESS, SUBNET_MATCH, UP, VIRTUAL
238    };
239
240
241    public static final Set<AttributeDefinition> NESTED_LIST_ATTRIBUTES = new HashSet<AttributeDefinition>(
242            Arrays.asList(INET_ADDRESS, NIC, NIC_MATCH, SUBNET_MATCH )
243    );
244
245    /** The wildcard criteria attributes */
246    public static final AttributeDefinition[] WILDCARD_ATTRIBUTES = new AttributeDefinition[] {ANY_ADDRESS, ANY_IPV4_ADDRESS, ANY_IPV6_ADDRESS };
247
248    public static final AttributeDefinition[] SIMPLE_ATTRIBUTES = new AttributeDefinition[] { LINK_LOCAL_ADDRESS, LOOPBACK,
249            MULTICAST, POINT_TO_POINT, PUBLIC_ADDRESS, SITE_LOCAL_ADDRESS, UP, VIRTUAL };
250
251    /**
252     * Create the AttributeDefinition for the nested 'not' / 'any' type.
253     *
254     * @param name the name
255     * @return the attribute definition
256     */
257    private static AttributeDefinition createNestedComplexType(final String name) {
258        return new AttributeDefinition(name, name, null, ModelType.OBJECT, true, false, MeasurementUnit.NONE, createNestedParamValidator(), ALTERNATIVES_ANY, null, AttributeAccess.Flag.RESTART_ALL_SERVICES) {
259            @Override
260            public void marshallAsElement(ModelNode resourceModel, XMLStreamWriter writer) throws XMLStreamException {
261                throw new UnsupportedOperationException();
262            }
263
264            @Override
265            public ModelNode addResourceAttributeDescription(final ResourceBundle bundle, final String prefix, final ModelNode resourceDescription) {
266                final ModelNode result = super.addResourceAttributeDescription(bundle, prefix, resourceDescription);
267                addNestedDescriptions(result, prefix, bundle);
268                return result;
269            }
270
271            @Override
272            public ModelNode addOperationParameterDescription(ResourceBundle bundle, String prefix, ModelNode operationDescription) {
273                final ModelNode result = super.addOperationParameterDescription(bundle, prefix, operationDescription);    //To change body of overridden methods use File | Settings | File Templates.
274                addNestedDescriptions(result, prefix, bundle);
275                return result;
276            }
277
278            void addNestedDescriptions(final ModelNode result, final String prefix, final ResourceBundle bundle) {
279                for(final AttributeDefinition def : NESTED_ATTRIBUTES) {
280                    final String bundleKey = prefix == null ? def.getName() : (prefix + "." + def.getName());
281                    result.get(VALUE_TYPE, def.getName(), DESCRIPTION).set(bundle.getString(bundleKey));
282                }
283            }
284
285            @Override
286            public ModelNode getNoTextDescription(boolean forOperation) {
287                final ModelNode model = super.getNoTextDescription(forOperation);
288                final ModelNode valueType = model.get(VALUE_TYPE);
289                for(final AttributeDefinition def : NESTED_ATTRIBUTES) {
290                    final AttributeDefinition current;
291                    if(NESTED_LIST_ATTRIBUTES.contains(def)) {
292                        current = wrapAsList(def);
293                    } else {
294                        current = def;
295                    }
296                    final ModelNode m = current.getNoTextDescription(forOperation);
297                    m.remove(ALTERNATIVES);
298                    valueType.get(current.getName()).set(m);
299                }
300                return model;
301            }
302        };
303
304    }
305
306    /**
307     * Wrap a simple attribute def as list.
308     *
309     * @param def the attribute definition
310     * @return the list attribute def
311     */
312    private static ListAttributeDefinition wrapAsList(final AttributeDefinition def) {
313        final ListAttributeDefinition list = new ListAttributeDefinition(def.getName(), true, def.getValidator()) {
314
315            @Override
316            public ModelNode getNoTextDescription(boolean forOperation) {
317                final ModelNode model = super.getNoTextDescription(forOperation);
318                setValueType(model);
319                return model;
320            }
321
322            @Override
323            protected void addValueTypeDescription(final ModelNode node, final ResourceBundle bundle) {
324                setValueType(node);
325            }
326            @Override
327            public void marshallAsElement(final ModelNode resourceModel, final XMLStreamWriter writer) throws XMLStreamException {
328                throw new RuntimeException();
329            }
330
331            @Override
332            protected void addAttributeValueTypeDescription(ModelNode node, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
333                setValueType(node);
334            }
335
336            @Override
337            protected void addOperationParameterValueTypeDescription(ModelNode node, String operationName, ResourceDescriptionResolver resolver, Locale locale, ResourceBundle bundle) {
338                setValueType(node);
339            }
340            private void setValueType(ModelNode node) {
341                node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
342            }
343        };
344        return list;
345    }
346
347    /**
348     * Create the nested complex attribute parameter validator.
349     *
350     * @return the parameter validator
351     */
352    static ParameterValidator createNestedParamValidator() {
353        return new ModelTypeValidator(ModelType.OBJECT, true, false, true) {
354            @Override
355            public void validateParameter(final String parameterName, final ModelNode value) throws OperationFailedException {
356                super.validateParameter(parameterName, value);
357
358                for(final AttributeDefinition def : NESTED_ATTRIBUTES) {
359                    final String name = def.getName();
360                    if(value.hasDefined(name)) {
361                        final ModelNode v = value.get(name);
362                        if(NESTED_LIST_ATTRIBUTES.contains(def)) {
363                            if (ModelType.LIST != v.getType()) {
364                                throw new OperationFailedException(new ModelNode().set(MESSAGES.invalidType(v.getType())));
365                            }
366                        } else {
367                            def.getValidator().validateParameter(name, v);
368                        }
369                    }
370                }
371            }
372        };
373    }
374
375    static String localName(final Element element) {
376        return element.getLocalName();
377    }
378
379}