use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.
the class SpannerEntryManager method merge.
@Override
public void merge(String dn, String[] objectClasses, List<AttributeDataModification> attributeDataModifications, Integer expirationValue) {
// Update entry
try {
List<AttributeDataModification> modifications = new ArrayList<AttributeDataModification>(attributeDataModifications.size());
for (AttributeDataModification attributeDataModification : attributeDataModifications) {
AttributeData attribute = attributeDataModification.getAttribute();
AttributeData oldAttribute = attributeDataModification.getOldAttribute();
String attributeName = null;
Object[] attributeValues = null;
Boolean multiValued = null;
if (attribute != null) {
attributeName = attribute.getName();
attributeValues = attribute.getValues();
multiValued = attribute.getMultiValued();
}
String oldAttributeName = null;
Object[] oldAttributeValues = null;
if (oldAttribute != null) {
oldAttributeName = oldAttribute.getName();
oldAttributeValues = oldAttribute.getValues();
}
AttributeDataModification modification = null;
AttributeModificationType modificationType = attributeDataModification.getModificationType();
if ((AttributeModificationType.ADD == modificationType) || (AttributeModificationType.FORCE_UPDATE == modificationType)) {
modification = createModification(modificationType, toInternalAttribute(attributeName), multiValued, attributeValues, oldAttributeValues);
} else {
if ((AttributeModificationType.REMOVE == modificationType)) {
if ((attribute == null) && isEmptyAttributeValues(oldAttribute)) {
// It's RDBS case. We don't need to set null to already empty table cell
continue;
}
modification = createModification(AttributeModificationType.REMOVE, toInternalAttribute(oldAttributeName), multiValued, oldAttributeValues, null);
} else if ((AttributeModificationType.REPLACE == modificationType)) {
modification = createModification(AttributeModificationType.REPLACE, toInternalAttribute(attributeName), multiValued, attributeValues, oldAttributeValues);
}
}
if (modification != null) {
modifications.add(modification);
}
}
if (modifications.size() > 0) {
boolean result = getOperationService().updateEntry(toSQLKey(dn).getKey(), objectClasses[0], modifications);
if (!result) {
throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn));
}
}
} catch (Exception ex) {
throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn), ex);
}
}
use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.
the class SqlEntryManager method merge.
@Override
public void merge(String dn, String[] objectClasses, List<AttributeDataModification> attributeDataModifications, Integer expirationValue) {
// Update entry
try {
List<AttributeDataModification> modifications = new ArrayList<AttributeDataModification>(attributeDataModifications.size());
for (AttributeDataModification attributeDataModification : attributeDataModifications) {
AttributeData attribute = attributeDataModification.getAttribute();
AttributeData oldAttribute = attributeDataModification.getOldAttribute();
String attributeName = null;
Object[] attributeValues = null;
Boolean multiValued = null;
if (attribute != null) {
attributeName = attribute.getName();
attributeValues = attribute.getValues();
multiValued = attribute.getMultiValued();
}
String oldAttributeName = null;
Object[] oldAttributeValues = null;
if (oldAttribute != null) {
oldAttributeName = oldAttribute.getName();
oldAttributeValues = oldAttribute.getValues();
}
AttributeDataModification modification = null;
AttributeModificationType modificationType = attributeDataModification.getModificationType();
if ((AttributeModificationType.ADD == modificationType) || (AttributeModificationType.FORCE_UPDATE == modificationType)) {
modification = createModification(modificationType, toInternalAttribute(attributeName), multiValued, attributeValues);
} else {
if ((AttributeModificationType.REMOVE == modificationType)) {
if ((attribute == null) && isEmptyAttributeValues(oldAttribute)) {
// It's RDBS case. We don't need to set null to already empty table cell
continue;
}
modification = createModification(AttributeModificationType.REMOVE, toInternalAttribute(oldAttributeName), multiValued, oldAttributeValues);
} else if ((AttributeModificationType.REPLACE == modificationType)) {
modification = createModification(AttributeModificationType.REPLACE, toInternalAttribute(attributeName), multiValued, attributeValues);
}
}
if (modification != null) {
modifications.add(modification);
}
}
if (modifications.size() > 0) {
boolean result = getOperationService().updateEntry(toSQLKey(dn).getKey(), objectClasses[0], modifications);
if (!result) {
throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn));
}
}
} catch (Exception ex) {
throw new EntryPersistenceException(String.format("Failed to update entry: '%s'", dn), ex);
}
}
use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.
the class SqlOperationServiceImpl method updateEntryImpl.
private boolean updateEntryImpl(TableMapping tableMapping, String key, List<AttributeDataModification> mods) throws PersistenceException {
try {
Map<String, String> columTypes = tableMapping.getColumTypes();
RelationalPathBase<Object> tableRelationalPath = buildTableRelationalPath(tableMapping);
SQLUpdateClause sqlUpdateQuery = this.sqlQueryFactory.update(tableRelationalPath);
for (AttributeDataModification attributeMod : mods) {
AttributeData attribute = attributeMod.getAttribute();
Path path = Expressions.stringPath(attribute.getName());
String attributeType = columTypes.get(attribute.getName().toLowerCase());
boolean multiValued = (attributeType != null) && isJsonColumn(tableMapping.getTableName(), attributeType);
AttributeModificationType type = attributeMod.getModificationType();
if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type)) {
if (multiValued || Boolean.TRUE.equals(attribute.getMultiValued())) {
sqlUpdateQuery.set(path, convertValueToDbJson(attribute.getValues()));
} else {
sqlUpdateQuery.set(path, attribute.getValue());
}
} else if (AttributeModificationType.REPLACE == type) {
if (multiValued || Boolean.TRUE.equals(attribute.getMultiValued())) {
sqlUpdateQuery.set(path, convertValueToDbJson(attribute.getValues()));
} else {
sqlUpdateQuery.set(path, attribute.getValue());
}
} else if (AttributeModificationType.REMOVE == type) {
sqlUpdateQuery.setNull(path);
} else {
throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
}
}
Predicate whereExp = ExpressionUtils.eq(Expressions.stringPath(SqlOperationService.DOC_ID), Expressions.constant(key));
long rowInserted = sqlUpdateQuery.where(whereExp).execute();
return rowInserted == 1;
} catch (QueryException ex) {
throw new PersistenceException("Failed to update entry", ex);
}
}
use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.
the class BaseEntryManager method collectAttributeModifications.
protected List<AttributeDataModification> collectAttributeModifications(List<PropertyAnnotation> propertiesAnnotations, Map<String, AttributeData> attributesToPersistMap, Map<String, AttributeData> attributesFromLdapMap, boolean isSchemaUpdate, AttributeModificationType schemaModificationType, boolean forceUpdate) {
List<AttributeDataModification> attributeDataModifications = new ArrayList<AttributeDataModification>();
for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) {
String propertyName = propertiesAnnotation.getPropertyName();
Annotation ldapAttribute;
ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), AttributeName.class);
if (ldapAttribute != null) {
String ldapAttributeName = ((AttributeName) ldapAttribute).name();
if (StringHelper.isEmpty(ldapAttributeName)) {
ldapAttributeName = propertyName;
}
ldapAttributeName = ldapAttributeName.toLowerCase();
AttributeData attributeToPersist = attributesToPersistMap.get(ldapAttributeName);
AttributeData attributeFromLdap = attributesFromLdapMap.get(ldapAttributeName);
// Remove processed attributes
attributesToPersistMap.remove(ldapAttributeName);
attributesFromLdapMap.remove(ldapAttributeName);
AttributeName ldapAttributeAnnotation = (AttributeName) ldapAttribute;
if (ldapAttributeAnnotation.ignoreDuringUpdate()) {
continue;
}
if (attributeFromLdap != null && attributeToPersist != null) {
// Modify DN entry attribute in DS
if (!attributeFromLdap.equals(attributeToPersist)) {
if (isEmptyAttributeValues(attributeToPersist) && !ldapAttributeAnnotation.updateOnly()) {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
} else {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REPLACE, attributeToPersist, attributeFromLdap));
}
}
} else if ((attributeFromLdap == null) && (attributeToPersist != null)) {
// Add entry attribute or change schema
if (isSchemaUpdate && (attributeToPersist.getValue() == null && Arrays.equals(attributeToPersist.getValues(), new Object[] {}))) {
continue;
}
AttributeModificationType modType = isSchemaUpdate ? schemaModificationType : AttributeModificationType.ADD;
if (AttributeModificationType.ADD == modType) {
if (isEmptyAttributeValues(attributeToPersist)) {
if (forceUpdate) {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeToPersist));
}
} else {
modType = forceUpdate ? AttributeModificationType.FORCE_UPDATE : modType;
attributeDataModifications.add(new AttributeDataModification(modType, attributeToPersist));
}
} else {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeToPersist));
}
} else if ((attributeFromLdap != null) && (attributeToPersist == null)) {
// or updateOnly = true
if (!ldapAttributeAnnotation.ignoreDuringRead() && !ldapAttributeAnnotation.updateOnly()) {
if (isEmptyAttributeValues(attributeFromLdap) && isStoreFullEntry()) {
// It's RDBS case. We don't need to set null to already empty table cell
continue;
}
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
}
} else if (forceUpdate && (attributeFromLdap == null) && (attributeToPersist == null)) {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, new AttributeData(ldapAttributeName, null)));
}
}
}
// Process properties with @AttributesList annotation
for (PropertyAnnotation propertiesAnnotation : propertiesAnnotations) {
Annotation ldapAttribute;
ldapAttribute = ReflectHelper.getAnnotationByType(propertiesAnnotation.getAnnotations(), AttributesList.class);
if (ldapAttribute != null) {
Map<String, AttributeName> ldapAttributesConfiguration = new HashMap<String, AttributeName>();
for (AttributeName ldapAttributeConfiguration : ((AttributesList) ldapAttribute).attributesConfiguration()) {
ldapAttributesConfiguration.put(ldapAttributeConfiguration.name(), ldapAttributeConfiguration);
}
// Prepare attributes for removal
for (AttributeData attributeFromLdap : attributesFromLdapMap.values()) {
String attributeName = attributeFromLdap.getName();
if (OBJECT_CLASS.equalsIgnoreCase(attributeName)) {
continue;
}
AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration.get(attributeName);
if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringUpdate()) {
continue;
}
if (!attributesToPersistMap.containsKey(attributeName.toLowerCase())) {
// Remove if attribute not marked as ignoreDuringRead = true
if ((ldapAttributeConfiguration == null) || ((ldapAttributeConfiguration != null) && !ldapAttributeConfiguration.ignoreDuringRead())) {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
}
}
}
// Prepare attributes for adding and replace
for (AttributeData attributeToPersist : attributesToPersistMap.values()) {
String attributeName = attributeToPersist.getName();
AttributeName ldapAttributeConfiguration = ldapAttributesConfiguration.get(attributeName);
if ((ldapAttributeConfiguration != null) && ldapAttributeConfiguration.ignoreDuringUpdate()) {
continue;
}
AttributeData attributeFromLdap = attributesFromLdapMap.get(attributeName.toLowerCase());
if (attributeFromLdap == null) {
// Add entry attribute or change schema
AttributeModificationType modType = isSchemaUpdate ? schemaModificationType : AttributeModificationType.ADD;
if (AttributeModificationType.ADD.equals(modType)) {
if (!isEmptyAttributeValues(attributeToPersist)) {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.ADD, attributeToPersist));
}
} else {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeToPersist));
}
} else if ((attributeFromLdap != null) && isEmptyAttributeValues(attributeToPersist)) {
if (isEmptyAttributeValues(attributeFromLdap) && isStoreFullEntry()) {
// It's RDBS case. We don't need to set null to already empty table cell
continue;
}
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
} else {
if (!attributeFromLdap.equals(attributeToPersist)) {
if (isEmptyAttributeValues(attributeToPersist) && (ldapAttributeConfiguration == null || !ldapAttributeConfiguration.updateOnly())) {
if (isEmptyAttributeValues(attributeFromLdap) && isStoreFullEntry()) {
// It's RDBS case. We don't need to set null to already empty table cell
continue;
}
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REMOVE, null, attributeFromLdap));
} else {
attributeDataModifications.add(new AttributeDataModification(AttributeModificationType.REPLACE, attributeToPersist, attributeFromLdap));
}
}
}
}
}
}
return attributeDataModifications;
}
use of io.jans.orm.model.AttributeDataModification.AttributeModificationType in project jans by JanssenProject.
the class SpannerOperationServiceImpl method updateEntryImpl.
private boolean updateEntryImpl(TableMapping tableMapping, String key, List<AttributeDataModification> mods) throws PersistenceException {
try {
MessageDigest messageDigest = getMessageDigestInstance();
Map<String, StructField> columTypes = tableMapping.getColumTypes();
WriteBuilder mutationBuilder = Mutation.newInsertOrUpdateBuilder(tableMapping.getTableName()).set(SpannerOperationService.DOC_ID).to(key);
List<Mutation> mutations = new LinkedList<>();
for (AttributeDataModification attributeMod : mods) {
AttributeData attribute = attributeMod.getAttribute();
AttributeModificationType type = attributeMod.getModificationType();
String attributeName = attribute.getName();
StructField attributeType = columTypes.get(attributeName.toLowerCase());
// If column not inside table we should check if there is child table
if (attributeType == null) {
TableMapping childTableMapping = connectionProvider.getChildTableMappingByKey(key, tableMapping, attributeName);
if (childTableMapping == null) {
throw new PersistenceException(String.format("Failed to update entry. Column '%s' is undefined", attributeName));
}
Map<String, StructField> childColumTypes = childTableMapping.getColumTypes();
StructField childAttributeType = childColumTypes.get(attributeName.toLowerCase());
// Build Mutation for child table
Map<String, Object> oldValues = null;
if ((attributeMod.getOldAttribute() != null) && (attributeMod.getOldAttribute().getValues() != null)) {
oldValues = new HashMap<>();
for (Object oldValue : attributeMod.getOldAttribute().getValues()) {
String dictDocId = getStringUniqueKey(messageDigest, oldValue);
oldValues.put(dictDocId, oldValue);
}
}
if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type) || (AttributeModificationType.REPLACE == type)) {
for (Object value : attribute.getValues()) {
WriteBuilder childMutationBuilder = Mutation.newInsertOrUpdateBuilder(childTableMapping.getTableName());
String dictDocId = getStringUniqueKey(messageDigest, value);
childMutationBuilder.set(SpannerOperationService.DOC_ID).to(key).set(SpannerOperationService.DICT_DOC_ID).to(dictDocId);
setMutationBuilderValue(childMutationBuilder, childAttributeType, value);
mutations.add(childMutationBuilder.build());
if (oldValues != null) {
oldValues.remove(dictDocId);
}
}
} else if (AttributeModificationType.REMOVE == type) {
// Build Mutation for child table
com.google.cloud.spanner.KeySet.Builder keySetBuilder = KeySet.newBuilder();
for (Object value : attribute.getValues()) {
String dictDocId = getStringUniqueKey(messageDigest, value);
keySetBuilder.addKey(Key.of(key, dictDocId));
}
Mutation childMutation = Mutation.delete(childTableMapping.getTableName(), keySetBuilder.build());
mutations.add(childMutation);
} else {
throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
}
if ((oldValues != null) && (oldValues.size() > 0)) {
com.google.cloud.spanner.KeySet.Builder keySetBuilder = KeySet.newBuilder();
for (String removeDictDocId : oldValues.keySet()) {
keySetBuilder.addKey(Key.of(key, removeDictDocId));
}
Mutation childMutation = Mutation.delete(childTableMapping.getTableName(), keySetBuilder.build());
mutations.add(childMutation);
}
} else {
if ((AttributeModificationType.ADD == type) || (AttributeModificationType.FORCE_UPDATE == type) || (AttributeModificationType.REPLACE == type)) {
setMutationBuilderValue(mutationBuilder, attributeType, attribute.getValues());
} else if (AttributeModificationType.REMOVE == type) {
removeMutationBuilderValue(mutationBuilder, attribute, attributeType);
} else {
throw new UnsupportedOperationException("Operation type '" + type + "' is not implemented");
}
}
}
mutations.add(0, mutationBuilder.build());
databaseClient.write(mutations);
return true;
} catch (SpannerException | IllegalStateException ex) {
throw new PersistenceException("Failed to update entry", ex);
}
}
Aggregations