/** * Orders attributes by defined order. * * <p>First looks to see if attributes are inherited, then looks at the declared fields based on * the attribute type. * * @param attributes list of data object attributes * @return re-ordered list of data object attributes */ public List<DataObjectAttribute> orderAttributesByDefinedOrder( List<DataObjectAttribute> attributes) { List<DataObjectAttribute> sorted = new ArrayList<DataObjectAttribute>(attributes.size()); Map<String, DataObjectAttribute> keyedAttributes = new HashMap<String, DataObjectAttribute>(attributes.size()); Map<String, List<DataObjectAttribute>> inheritedAttributes = new HashMap<String, List<DataObjectAttribute>>(); for (DataObjectAttribute attr : attributes) { if (attr.isInherited()) { List<DataObjectAttribute> inheritedByProperty = inheritedAttributes.get(attr.getInheritedFromParentAttributeName()); if (inheritedByProperty == null) { inheritedByProperty = new ArrayList<DataObjectAttribute>(); inheritedAttributes.put(attr.getInheritedFromParentAttributeName(), inheritedByProperty); } inheritedByProperty.add(attr); } else { keyedAttributes.put(attr.getName(), attr); } } for (Field f : getType().getDeclaredFields()) { DataObjectAttribute attr = keyedAttributes.get(f.getName()); if (attr != null) { sorted.add(attr); keyedAttributes.remove(f.getName()); } if (inheritedAttributes.containsKey(f.getName())) { sorted.addAll(inheritedAttributes.get(f.getName())); } } sorted.addAll(keyedAttributes.values()); return sorted; }
protected UifDisplayHint getHintOfType(DataObjectAttribute attr, UifDisplayHintType hintType) { if (attr != null && attr.getDisplayHints() != null) { for (UifDisplayHint hint : attr.getDisplayHints()) { if (hint.value().equals(hintType)) { return hint; } } } return null; }
/** * Sets attributes. * * <p>Looks at merge actions when adding, so not all attributes are added. * * @param attributes list of data object attributes */ public void setAttributes(List<DataObjectAttribute> attributes) { if (attributes == null) { attributes = Collections.emptyList(); } this.attributes = Collections.unmodifiableList(attributes); mergedAttributes = null; attributeMap = new HashMap<String, DataObjectAttribute>(attributes.size()); removedAttributeNames = new ArrayList<String>(); for (DataObjectAttribute attr : attributes) { // TODO: This is not quite correct - we really only want to not add the NO_OVERRIDE items if // they are // overriding something. However, at the point this is running, we don't know whether we will // be embedding // anything... if (attr.getMergeAction() != MetadataMergeAction.REMOVE && attr.getMergeAction() != MetadataMergeAction.NO_OVERRIDE) { attributeMap.put(attr.getName(), attr); } // since the attribute will still exist in the embedded metadata, we need to put a block in on // the standard // cascade if (attr.getMergeAction() == MetadataMergeAction.REMOVE) { removedAttributeNames.add(attr.getName()); } } }
/** {@inheritDoc} */ @Override public DataObjectAttribute getAttribute(String attributeName) { if (attributeName == null) { return null; } DataObjectAttribute attribute = null; // attempt to get it from the local attribute map (if any attributed defined locally) if (attributes != null) { attribute = attributeMap.get(attributeName); } // if we don't find one, but we have an embedded metadata object, check it if (attribute == null && embedded != null) { attribute = embedded.getAttribute(attributeName); // but, ensure it's not on the removed attribute list if (attribute != null && removedAttributeNames != null && removedAttributeNames.contains(attribute.getName())) { attribute = null; } } return attribute; }
protected Control getControlInstance( AttributeDefinition attrDef, DataObjectAttribute dataObjectAttribute) { Control c = null; // Check for the hidden hint - if present - then use that control type if (dataObjectAttribute != null && hasHintOfType(dataObjectAttribute, UifDisplayHintType.HIDDEN)) { c = ComponentFactory.getHiddenControl(); } else if (attrDef.getOptionsFinder() != null) { // if a values finder has been established, use a radio button group or drop-down list if (dataObjectAttribute != null && hasHintOfType(dataObjectAttribute, UifDisplayHintType.RADIO)) { c = ComponentFactory.getRadioGroupControl(); } else { c = ComponentFactory.getSelectControl(); } } else if (attrDef.getName().endsWith(".principalName") && dataObjectAttribute != null) { // FIXME: JHK: Yes, I know this is a *HORRIBLE* hack - but the alternative // would look even more "hacky" and error-prone c = ComponentFactory.getUserControl(); // Need to find the relationship information // get the relationship ID by removing .principalName from the attribute name String relationshipName = StringUtils.removeEnd(attrDef.getName(), ".principalName"); DataObjectMetadata metadata = dataObjectService .getMetadataRepository() .getMetadata(dataObjectAttribute.getOwningType()); if (metadata != null) { DataObjectRelationship relationship = metadata.getRelationship(relationshipName); if (relationship != null && CollectionUtils.isNotEmpty(relationship.getAttributeRelationships())) { ((UserControl) c) .setPrincipalIdPropertyName( relationship.getAttributeRelationships().get(0).getParentAttributeName()); ((UserControl) c) .setPersonNamePropertyName( relationshipName + "." + KimConstants.AttributeConstants.NAME); ((UserControl) c).setPersonObjectPropertyName(relationshipName); } } else { LOG.warn( "Attempt to pull relationship name: " + relationshipName + " resulted in missing metadata when looking for: " + dataObjectAttribute.getOwningType()); } } else { switch (attrDef.getDataType()) { case STRING: // TODO: Determine better way to store the "200" metric below if (attrDef.getMaxLength() != null && attrDef.getMaxLength().intValue() > 200) { c = ComponentFactory.getTextAreaControl(); } else { c = ComponentFactory.getTextControl(); } break; case BOOLEAN: c = ComponentFactory.getCheckboxControl(); break; case DATE: case DATETIME: case TRUNCATED_DATE: c = ComponentFactory.getDateControl(); break; case CURRENCY: case DOUBLE: case FLOAT: case INTEGER: case LARGE_INTEGER: case LONG: case PRECISE_DECIMAL: c = ComponentFactory.getTextControl(); break; case MARKUP: c = ComponentFactory.getTextAreaControl(); break; default: c = ComponentFactory.getTextControl(); break; } } return c; }