View Javadoc

1   /*
2    * Copyright 2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.properties.jboss.extension.resources.util;
17  
18  import java.util.LinkedHashMap;
19  import java.util.Locale;
20  import java.util.Map;
21  import java.util.ResourceBundle;
22  
23  import javax.xml.stream.XMLStreamException;
24  import javax.xml.stream.XMLStreamWriter;
25  
26  import org.jboss.as.controller.MapAttributeDefinition;
27  import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
28  import org.jboss.as.controller.descriptions.ResourceDescriptionResolver;
29  import org.jboss.as.controller.operations.validation.ModelTypeValidator;
30  import org.jboss.as.controller.operations.validation.ParameterValidator;
31  import org.jboss.dmr.ModelNode;
32  import org.jboss.dmr.ModelType;
33  import org.jboss.dmr.Property;
34  
35  /**
36   * A map of simple map values.
37   */
38  public final class SimpleMapAttributeDefinition extends MapAttributeDefinition
39  {
40    // ********************************* Fields *********************************
41  
42    // --- constants ------------------------------------------------------------
43  
44    // --- members --------------------------------------------------------------
45  
46    /**
47     * The name of the XML element that encloses the items named by
48     * {@link #xmlName}.
49     */
50    private final String wrapperXmlName;
51  
52    /**
53     * The name of the XML attribute that references the type name.
54     */
55    private final String xmlAttributeName;
56  
57    // ****************************** Initializer *******************************
58  
59    // ****************************** Constructors ******************************
60  
61    /**
62     * Default constructor.
63     *
64     * @param wrapperXmlName the name of the XML element that encloses the items
65     *          named by {@link #xmlName}.
66     * @param name the name of the map attribute.
67     * @param xmlName the name of the XML element.
68     * @param xmlAttributeName the name of the XML attribute that references the
69     *          type name.
70     * @param allowNull the flag to mark the attribute containing the tuples as
71     *          optional ( <code>true</code>) or mandatory (<code>false</code>).
72     * @param elementValidator the validator of the tuple values.
73     */
74    private SimpleMapAttributeDefinition(final String wrapperXmlName,
75        final String name, final String xmlName, final String xmlAttributeName,
76        final boolean allowNull, final ParameterValidator elementValidator)
77    {
78      super(name, xmlName, allowNull, 0, Integer.MAX_VALUE, elementValidator,
79          null, null);
80      this.wrapperXmlName = wrapperXmlName;
81      this.xmlAttributeName = xmlAttributeName;
82    }
83  
84    // ****************************** Inner Classes *****************************
85  
86    /**
87     * Builds instances of {@link SimpleMapAttributeDefinition}.
88     */
89    public static final class Builder
90    {
91      // ******************************** Fields ********************************
92  
93      // --- constants ----------------------------------------------------------
94  
95      // --- members ------------------------------------------------------------
96  
97      /**
98       * The name of the XML element that encloses the items named by
99       * {@link #xmlName}.
100      */
101     private String wrapperXmlName;
102 
103     /**
104      * The name of the map attribute.
105      */
106     private String name;
107 
108     /**
109      * The name of the XML element where the attribute is the key and the
110      * contents is the value.
111      */
112     private String xmlName;
113 
114     /**
115      * The name of the XML attribute that references the type name.
116      */
117     private String xmlAttributeName;
118 
119     /**
120      * The type of the value.
121      */
122     private ModelType type;
123 
124     /**
125      * The flag to mark the attribute containing the tuples as optional (
126      * <code>true</code>) or mandatory (<code>false</code>).
127      */
128     private boolean allowNull;
129 
130     /**
131      * Flag to mark the value being allowed to contain expressions.
132      */
133     private boolean allowExpression;
134 
135     /**
136      * The validator for values.
137      */
138     private ParameterValidator validator;
139 
140     // ***************************** Initializer ******************************
141 
142     // ***************************** Constructors *****************************
143 
144     /**
145      * Default constructor.
146      */
147     public Builder()
148     {
149     }
150 
151     // ***************************** Inner Classes ****************************
152 
153     // ******************************** Methods *******************************
154 
155     // --- init ---------------------------------------------------------------
156 
157     // --- get&set ------------------------------------------------------------
158 
159     /**
160      * Sets the name of the XML element that encloses the items named by
161      * {@link #setXmlName() xmlName}.
162      *
163      * @param wrapperXmlName the name of the XML element that encloses the items
164      *          named by {@link #setXmlName() xmlName}.
165      * @return a reference to this builder.
166      */
167     public Builder withWrapperXmlName(final String wrapperXmlName)
168     {
169       this.wrapperXmlName = wrapperXmlName;
170       return this;
171     }
172 
173     /**
174      * Sets the name of the map attribute.
175      *
176      * @param name the name of the attribute.
177      * @return a reference to this builder.
178      */
179     public Builder withName(final String name)
180     {
181       this.name = name;
182       return this;
183     }
184 
185     /**
186      * Sets the name of the XML element where the attribute is the key and the
187      * contents is the value.
188      *
189      * @param xmlName the name of the XML element where the attribute is the key
190      *          and the contents is the value.
191      * @return a reference to this builder.
192      */
193     public Builder withXmlName(final String xmlName)
194     {
195       this.xmlName = xmlName;
196       return this;
197     }
198 
199     /**
200      * Sets the name of the XML attribute that references the type name.
201      *
202      * @param xmlAttributeName the name of the XML attribute that references the
203      *          type name.
204      * @return a reference to this builder.
205      */
206     public Builder withXmlAttributeName(final String xmlAttributeName)
207     {
208       this.xmlAttributeName = xmlAttributeName;
209       return this;
210     }
211 
212     /**
213      * Sets the type of the value.
214      *
215      * @param type the type of the value.
216      * @return a reference to this builder.
217      */
218     public Builder withType(final ModelType type)
219     {
220       this.type = type;
221       return this;
222     }
223 
224     /**
225      * Sets the flag to mark the attribute containing the tuples as optional (
226      * <code>true</code>) or mandatory (<code>false</code>).
227      *
228      * @param allowNull the flag to mark the attribute containing the tuples as
229      *          optional ( <code>true</code>) or mandatory (<code>false</code>).
230      * @return a reference to this builder.
231      */
232     public Builder withAllowNull(final boolean allowNull)
233     {
234       this.allowNull = allowNull;
235       return this;
236     }
237 
238     /**
239      * Sets the value for allowExpression.
240      * <p>
241      * Flag to mark the value being allowed to contain expressions.
242      *
243      * @param allowExpression the value for allowExpression.
244      * @return a reference to this builder.
245      */
246     public Builder withAllowExpression(final boolean allowExpression)
247     {
248       this.allowExpression = allowExpression;
249       return this;
250     }
251 
252     /**
253      * Sets the validator for values.
254      *
255      * @param validator the validator for values.
256      * @return a reference to this builder.
257      */
258     public Builder withValidator(final ParameterValidator validator)
259     {
260       this.validator = validator;
261       return this;
262     }
263 
264     // --- business -----------------------------------------------------------
265 
266     /**
267      * Creates the instance.
268      *
269      * @return the instance.
270      */
271     public SimpleMapAttributeDefinition build()
272     {
273       if (type == null)
274       {
275         type = ModelType.STRING;
276       }
277       if (xmlAttributeName == null)
278       {
279         xmlAttributeName = "type";
280       }
281 
282       if (validator == null)
283       {
284         validator = new ModelTypeValidator(type, allowNull, allowExpression);
285       }
286 
287       return new SimpleMapAttributeDefinition(wrapperXmlName, name, xmlName,
288           xmlAttributeName, allowNull, validator);
289     }
290 
291     // --- object basics ------------------------------------------------------
292   }
293 
294   // ********************************* Methods ********************************
295 
296   // --- init -----------------------------------------------------------------
297 
298   // --- get&set --------------------------------------------------------------
299 
300   /**
301    * Returns the name of the XML element that encloses the items named by
302    * {@link #getXmlName() xmlName}.
303    *
304    * @return the name of the XML element that encloses the items named by
305    *         {@link #getXmlName() xmlName}.
306    */
307   public String getWrapperXmlName()
308   {
309     return wrapperXmlName;
310   }
311 
312   /**
313    * Returns the name of the XML attribute that references the type name.
314    *
315    * @return the name of the XML attribute that references the type name.
316    */
317   public String getXmlAttributeName()
318   {
319     return xmlAttributeName;
320   }
321 
322   // --- business -------------------------------------------------------------
323 
324   @Override
325   protected void addValueTypeDescription(final ModelNode node,
326       final ResourceBundle bundle)
327   {
328     setValueType(node);
329   }
330 
331   @Override
332   protected void addAttributeValueTypeDescription(final ModelNode result,
333       final ResourceDescriptionResolver resolver, final Locale locale,
334       final ResourceBundle bundle)
335   {
336     setValueType(result);
337   }
338 
339   @Override
340   protected void addOperationParameterValueTypeDescription(
341       final ModelNode result, final String operationName,
342       final ResourceDescriptionResolver resolver, final Locale locale,
343       final ResourceBundle bundle)
344   {
345     setValueType(result);
346   }
347 
348   void setValueType(final ModelNode node)
349   {
350     node.get(ModelDescriptionConstants.VALUE_TYPE).set(ModelType.STRING);
351     if (isAllowExpression())
352     {
353       node.get(ModelDescriptionConstants.EXPRESSIONS_ALLOWED).set(
354           new ModelNode(true));
355     }
356   }
357 
358   @Override
359   public void marshallAsElement(final ModelNode resourceModel,
360       final XMLStreamWriter writer) throws XMLStreamException
361   {
362     final String modelName = getName();
363     final ModelNode mapModel = resourceModel.get(modelName);
364     writer.writeStartElement(wrapperXmlName == null ? modelName
365         : wrapperXmlName);
366 
367     for (final ModelNode listNode : mapModel.asList())
368     {
369       final Property property = listNode.asProperty();
370       writer.writeStartElement(getXmlName());
371       writer.writeAttribute(xmlAttributeName, property.getName());
372       writer.writeCharacters(property.getValue().asString());
373       writer.writeEndElement();
374     }
375 
376     writer.writeEndElement();
377   }
378 
379   public Map<String, String> toStringMap(final ModelNode resourceModel)
380   {
381     final Map<String, String> map = new LinkedHashMap<String, String>();
382 
383     final String modelName = getName();
384     final ModelNode mapModel = resourceModel.get(modelName);
385     if (mapModel.isDefined())
386     {
387       for (final ModelNode listNode : mapModel.asList())
388       {
389         final Property property = listNode.asProperty();
390         final String key = property.getName();
391         final String value = property.getValue().asString();
392         map.put(key, value);
393       }
394     }
395 
396     return map;
397   }
398 
399   // --- object basics --------------------------------------------------------
400 
401 }