@Override protected FormItem<?>[] doGetCustomFields() { TextBoxItem pathItem = new TextBoxItem("url", "KeyStore Path"); pathItem.getInputElement().getStyle().setWidth(300, Style.Unit.PX); this.relativeTo = new TextBoxItem("relativeTo", "Path Relative To"); this.relativeTo.getInputElement().getStyle().setWidth(300, Style.Unit.PX); this.relativeTo.setRequired(false); PasswordBoxItem passwdItem = new PasswordBoxItem("passwd", "KeyStore Password"); passwdItem.getInputElement().getStyle().setWidth(150, Style.Unit.PX); TextBoxItem signKeyAliasItem = new TextBoxItem("signKeyAlias", "Signing Key Alias"); signKeyAliasItem.getInputElement().getStyle().setWidth(150, Style.Unit.PX); PasswordBoxItem signKeyPasswdItem = new PasswordBoxItem("signKeyPasswd", "Signing Key Password"); signKeyPasswdItem.getInputElement().getStyle().setWidth(150, Style.Unit.PX); return new FormItem[] { pathItem, this.relativeTo, passwdItem, signKeyAliasItem, signKeyPasswdItem }; }
public FormAssets build() { // pre-requisite if (createMode && !modelDescription.hasDefined("operations")) { throw new IllegalStateException("Operation descriptions not defined"); } this.form = new ModelNodeForm(this.address, this.securityContext); this.form.setNumColumns(2); this.form.setEnabled(false); assert modelDescription.hasDefined("attributes") : "Invalid model description. Expected child 'attributes'"; List<Property> attributeDescriptions = new ArrayList<Property>(); if (createMode && modelDescription.get("operations").get("add").hasDefined("request-properties")) { attributeDescriptions = modelDescription.get("operations").get("add").get("request-properties").asPropertyList(); } else if (!createMode) { attributeDescriptions = modelDescription.get("attributes").asPropertyList(); } // sort fields if (!unsorted) { Collections.sort( attributeDescriptions, new Comparator<Property>() { @Override public int compare(Property property, Property property1) { return property.getName().compareTo(property1.getName()); } }); } // catch-all directive, if no explicit attributes given if (includes.isEmpty()) { for (Property attr : attributeDescriptions) { includes.add(attr.getName()); } } // in any case remove attributes marked for exclusion includes.removeAll(excludes); LinkedList<FormItem> requiredItems = new LinkedList<FormItem>(); LinkedList<FormItem> optionalItems = new LinkedList<FormItem>(); SafeHtmlBuilder helpTexts = new SafeHtmlBuilder(); helpTexts.appendHtmlConstant("<table class='help-attribute-descriptions'>"); Map<String, ModelNode> defaultValues = new HashMap<String, ModelNode>(); int numWritable = 0; boolean hasRequired = false; // for some decision below we need to know wether or not required attributes exist at all if (requiredOnly) { for (Property attr : attributeDescriptions) { ModelNode value = attr.getValue(); boolean required = isRequired(value); boolean readOnly = value.get("access-type").asString().equals("read-only"); if (required & !readOnly) { hasRequired = true; break; } } } Set<String[]> unsupportedTypes = new HashSet<>(); for (String attribute : includes) { for (Property attr : attributeDescriptions) { boolean isRuntime = attr.getValue().get("storage").asString().equals("runtime"); boolean isConfig = !attr.getValue().get("storage").asString().equals("runtime"); // TODO: verify statement if (runtimeAttributes == false && isRuntime) { continue; } if (configAttributes == false && isConfig) { continue; } if (!attr.getName().equals(attribute)) continue; // ------- // Attribute meta data // name char[] attrName = attr.getName().toCharArray(); attrName[0] = Character.toUpperCase(attrName[0]); // field label String label = new String(attrName).replace("-", " "); ModelNode attrDesc = attr.getValue(); // skip deprecated attributes if (attrDesc.hasDefined("deprecated")) { // Log.error("Skip deprecated attribute '" + attr.getName() + "'"); continue; } // type ModelType type = ModelType.valueOf(attrDesc.get("type").asString().toUpperCase()); // default value if (attrDesc.hasDefined("default")) { ModelNode defaultValue = attrDesc.get("default"); ModelNode value = new ModelNode(); // value.set(type, ModelNodeForm.downCast(defaultValue)); setValue( value, type, ModelNodeForm.downCast(defaultValue, attrDesc)); // workaround for numeric types defaultValues.put(attr.getName(), value); } // read-only final boolean readOnly = attrDesc.hasDefined("access-type") ? attrDesc.get("access-type").asString().equals("read-only") : false; // nillable boolean isRequired = isRequired(attrDesc); // createMode flag if ((createMode && readOnly)) continue; // requiredOnly flag if (requiredOnly && hasRequired && !isRequired) continue; // count writable attributes if (!readOnly && !isRuntime) numWritable++; // ------- // help helpTexts.appendHtmlConstant("<tr class='help-field-row'>"); helpTexts.appendHtmlConstant("<td class='help-field-name'>"); helpTexts.appendEscaped(label).appendEscaped(": "); helpTexts.appendHtmlConstant("</td>"); helpTexts.appendHtmlConstant("<td class='help-field-desc'>"); try { String descWorkaround = attrDesc.get("description").asString(); helpTexts.appendHtmlConstant(descWorkaround.equals("null") ? "n/a" : descWorkaround); } catch (Throwable e) { // ignore parse errors helpTexts.appendHtmlConstant("<i>Failed to parse description</i>"); } helpTexts.appendHtmlConstant("</td>"); helpTexts.appendHtmlConstant("</tr>"); FormItem formItem = null; // explicitly created form items (monkey patching) if (itemFactories.containsKey(attr.getName())) { formItem = itemFactories.get(attr.getName()).create(attr); } // not created by explicit factory if (null == formItem) { switch (type) { case BOOLEAN: formItem = new CheckBoxItem(attr.getName(), label); formItem.setRequired(isRequired); formItem.setEnabled(!readOnly && !isRuntime); break; case DOUBLE: formItem = new DoubleFormItem(attr.getName(), label); formItem.setRequired(isRequired); formItem.setEnabled(!readOnly && !isRuntime); break; case LONG: boolean allowNegativeValues = false; if (attrDesc.hasDefined("default")) allowNegativeValues = attrDesc.get("default").asLong() < 0; formItem = new NumberBoxItem(attr.getName(), label, allowNegativeValues); formItem.setRequired(isRequired); formItem.setEnabled(!readOnly && !isRuntime); break; case BIG_DECIMAL: formItem = new NumberBoxItem(attr.getName(), label); formItem.setRequired(isRequired); formItem.setEnabled(!readOnly && !isRuntime); break; case INT: if (attrDesc.hasDefined("min") && attrDesc.hasDefined("max")) { formItem = new NumberBoxItem( attr.getName(), label, attrDesc.get("min").asLong(), attrDesc.get("max").asLong()); } else { formItem = new NumberBoxItem(attr.getName(), label); } formItem.setRequired(isRequired); formItem.setEnabled(!readOnly && !isRuntime); break; case LIST: formItem = new ListItem(attr.getName(), label); formItem.setRequired(isRequired); formItem.setEnabled(!readOnly && !isRuntime); break; case STRING: if (attrDesc.get("allowed").isDefined()) { List<ModelNode> allowed = attrDesc.get("allowed").asList(); Set<String> allowedValues = new HashSet<String>(allowed.size()); for (ModelNode value : allowed) allowedValues.add(value.asString()); final boolean isNillable = attrDesc.hasDefined(NILLABLE) && attrDesc.get(NILLABLE).asBoolean(); ComboBoxItem combo = new ComboBoxItem(attr.getName(), label, isNillable); combo.setValueMap(allowedValues); combo.setEnabled(!readOnly && !isRuntime); combo.setRequired(isRequired); formItem = combo; } else { formItem = createSuggestBoxForCapabilityReference(attr, label, isRequired); if (formItem == null) { // there is no capability-reference TextBoxItem textBoxItem = new TextBoxItem(attr.getName(), label); textBoxItem.setAllowWhiteSpace(true); textBoxItem.setRequired(isRequired); textBoxItem.setEnabled(!readOnly && !isRuntime); formItem = textBoxItem; } } // TODO: Support for TextAreaItem break; case OBJECT: if (attrDesc.has("value-type") && attrDesc.get("value-type").asString().equals("STRING")) { PropertyListItem propList = new PropertyListItem(attr.getName(), label); propList.setRequired(isRequired); propList.setEnabled(!readOnly && !isRuntime); formItem = propList; break; } default: { unsupportedTypes.add(new String[] {attr.getName(), type.toString()}); Log.error("Unsupported ModelType " + type + ", attribute '" + attr.getName() + "'"); } } } if (formItem != null) { if (createMode) { if (isRequired && includeOptionals) requiredItems.add(formItem); else optionalItems.add(formItem); } else { requiredItems.add(formItem); } // attribute meta data attached to form item formItem.setMetadata(attrDesc); } } } // some resources already contain a name attribute FormItem nameItem = null; if (createMode) { for (FormItem item : requiredItems) { if ("name".equals(item.getName())) { nameItem = item; break; } } for (FormItem item : optionalItems) { if ("name".equals(item.getName())) { nameItem = item; break; } } } // remove so it can be prepended if (nameItem != null) { requiredItems.remove(nameItem); optionalItems.remove(nameItem); } // distinguish required and optional fields (createMode) if (requiredItems.isEmpty()) { // no required fields explicitly given, treat all fields as required if (createMode) { optionalItems.addFirst(new TextBoxItem("name", "Name", true)); numWritable++; } form.setFields(optionalItems.toArray(new FormItem[] {})); } else { if (createMode) { requiredItems.addFirst(new TextBoxItem("name", "Name", true)); numWritable++; } form.setFields(requiredItems.toArray(new FormItem[] {})); if (optionalItems.size() > 0) form.setFieldsInGroup( "Optional Fields", new DisclosureGroupRenderer(), optionalItems.toArray(new FormItem[] {})); } // form meta data form.setDefaults(defaultValues); form.setHasWritableAttributes(numWritable > 0); FormAssets formAssets = new FormAssets(form, helpTexts.toSafeHtml()); formAssets.setUnsupportedTypes(unsupportedTypes); return formAssets; }