private boolean hasBlobField(List<Field> fields) { for (Field field : fields) { if (field.getType().isBlob()) { return true; } } return false; }
private static void assertRelationshipIsHistoryCompatible( Field field, RelationshipHolder holder, List<Entity> allEntities) { Entity relatedEntity = findEntityByName(holder.getRelatedClass(), allEntities); if (!hasCorrectTrackingSettings(field, relatedEntity, holder)) { String relatedClassName = relatedEntity == null ? "null" : relatedEntity.getClassName(); throw new InvalidEntitySettingsException(field.getEntity().getClassName(), relatedClassName); } }
private static MultiValueMap<String, String> validateRelationship( MultiValueMap<String, String> unresolvedRelations, Field field, RelationshipHolder holder) { List<String> relatedClasses = unresolvedRelations.get(holder.getRelatedClass()); if (relatedClasses != null && relatedClasses.contains(field.getEntity().getClassName()) && StringUtils.isEmpty(holder.getRelatedField())) { throw new InvalidRelationshipException( holder.getRelatedClass(), field.getEntity().getClassName()); } if (holder.hasUnresolvedRelation() && !field.getEntity().getClassName().equals(holder.getRelatedClass())) { unresolvedRelations.add(field.getEntity().getClassName(), holder.getRelatedClass()); } return unresolvedRelations; }
/** * Resolves correct task parameter type, based on the MDS field type. * * @param field MDS field * @return matching task parameter type */ public static String resolveType(Field field) { Type type = field.getType(); if (type.isCombobox()) { return resolveComboboxType(new ComboboxHolder(field)); } else { String matchedType = TYPE_MAPPING.get(type.getDisplayName()); return null != matchedType ? matchedType : UNKNOWN; } }
private String lookupParamDescription( Field field, LookupFieldType lookupFieldType, Locale locale) { // start with tooltip or name if tooltip is not defined // for sets and ranges append appropriate info StringBuilder desc = new StringBuilder( StringUtils.isNotBlank(field.getTooltip()) ? field.getTooltip() : field.getName()); switch (lookupFieldType) { case SET: desc.append(" - ").append(msg(locale, SET_PARAM_DESC_KEY)); break; case RANGE: desc.append(" - ").append(msg(locale, RANGE_PARAM_DESC_KEY)); break; default: break; } return desc.toString(); }
private static boolean hasCorrectTrackingSettings( Field field, Entity relatedEntity, RelationshipHolder holder) { boolean recordsHistory = field.getEntity().isRecordHistory(); boolean relatedRecordsHistory = relatedEntity.isRecordHistory(); if (holder.isBiDirectional()) { // Both sides of bi-directional relationship must have the same history tracking settings return !(recordsHistory ^ relatedRecordsHistory); } else { // For uni-directional relationship, the related side must not have more strict options than // the entity that defines the relationship return recordsHistory ? relatedRecordsHistory : true; } }
private void buildDefinitionProperties( Map<String, Property> properties, List<String> required, Entity entity, boolean includeAuto, boolean includeId) { if (includeId) { properties.put(Constants.Util.ID_FIELD_NAME, new Property(INTEGER_TYPE, INT64_FORMAT)); } for (Field field : entity.getFields()) { final String fieldName = field.getName(); if (field.isExposedViaRest()) { // auto generated fields included only in responses if (!field.isAutoGenerated() || includeAuto) { Property property = SwaggerFieldConverter.fieldToProperty(field); properties.put(fieldName, property); if (field.isRequired()) { required.add(fieldName); } } } } }
/** * Takes a list of entities and sorts them, according to relationships they have. The entities * that have uni-directional relationship with another entity, will be moved to the position * behind the entity they are related with. The bi-directional relationships are not sorted, * moreover if invalid bi-directional relationship is found, an exception is thrown. * * @param list Initial list of entities to sort * @return List of entities, sorted by relationship */ public static List<Entity> sortByHasARelation(List<Entity> list) { List<Entity> sorted = new ArrayList<>(list); MultiValueMap<String, String> unresolvedRelations = new LinkedMultiValueMap<>(); // we need to check if classes have 'has-a' relation // these classes should be later in list // we do that after all entities will be added to sorted list for (int i = 0; i < sorted.size(); ++i) { Entity entity = sorted.get(i); List<Field> fields = (List<Field>) CollectionUtils.select( entity.getFields(), new Predicate() { @Override public boolean evaluate(Object object) { return object instanceof Field && ((Field) object).getType().isRelationship(); } }); if (CollectionUtils.isNotEmpty(fields)) { int max = i; for (Field field : fields) { final RelationshipHolder holder = new RelationshipHolder(field); // For each field we perform a validation to spot circular, unresolvable relations, // which means the data model is incorrect unresolvedRelations = validateRelationship(unresolvedRelations, field, holder); assertRelationshipIsHistoryCompatible(field, holder, list); Entity relation = (Entity) CollectionUtils.find( sorted, new Predicate() { @Override public boolean evaluate(Object object) { return object instanceof Entity && ((Entity) object) .getClassName() .equalsIgnoreCase(holder.getRelatedClass()); } }); // In case the relation is bidirectional, we shouldn't move the class, // in order to avoid infinite loop boolean biDirectional = field.getMetadata(RELATED_FIELD) != null; max = Math.max(max, biDirectional ? -1 : sorted.indexOf(relation)); } if (max != i) { sorted.remove(i); --i; if (max < sorted.size()) { sorted.add(max, entity); } else { sorted.add(entity); } } } } return sorted; }