/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}