use of io.jans.orm.model.AttributeDataModification in project jans by JanssenProject.
the class LdapEntryManager method merge.
@Override
public void merge(String dn, String[] objectClasses, List<AttributeDataModification> attributeDataModifications, Integer expiration) {
// Update entry
try {
List<Modification> modifications = new ArrayList<Modification>(attributeDataModifications.size());
for (AttributeDataModification attributeDataModification : attributeDataModifications) {
AttributeData attribute = attributeDataModification.getAttribute();
AttributeData oldAttribute = attributeDataModification.getOldAttribute();
String attributeName = null;
String[] attributeValues = null;
if (attribute != null) {
attributeName = attribute.getName();
attributeValues = attribute.getStringValues();
}
String oldAttributeName = null;
String[] oldAttributeValues = null;
if (oldAttribute != null) {
oldAttributeName = oldAttribute.getName();
oldAttributeValues = oldAttribute.getStringValues();
}
Modification modification = null;
if (AttributeModificationType.ADD.equals(attributeDataModification.getModificationType())) {
modification = createModification(ModificationType.ADD, attributeName, attributeValues);
} else {
if (AttributeModificationType.REMOVE.equals(attributeDataModification.getModificationType())) {
modification = createModification(ModificationType.DELETE, oldAttributeName, oldAttributeValues);
} else if (AttributeModificationType.REPLACE.equals(attributeDataModification.getModificationType())) {
if (attributeValues.length == 1) {
modification = createModification(ModificationType.REPLACE, attributeName, attributeValues);
} else {
String[] oldValues = ArrayHelper.arrayClone(oldAttributeValues);
String[] newValues = ArrayHelper.arrayClone(attributeValues);
Arrays.sort(oldValues);
Arrays.sort(newValues);
boolean[] retainOldValues = new boolean[oldValues.length];
Arrays.fill(retainOldValues, false);
List<String> addValues = new ArrayList<String>();
List<String> removeValues = new ArrayList<String>();
// Add new values
for (String value : newValues) {
int idx = Arrays.binarySearch(oldValues, value, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.toLowerCase().compareTo(o2.toLowerCase());
}
});
if (idx >= 0) {
// Old values array contains new value. Retain
// old value
retainOldValues[idx] = true;
} else {
// This is new value
addValues.add(value);
}
}
// Remove values which we don't have in new values
for (int i = 0; i < oldValues.length; i++) {
if (!retainOldValues[i]) {
removeValues.add(oldValues[i]);
}
}
if (removeValues.size() > 0) {
Modification removeModification = createModification(ModificationType.DELETE, attributeName, removeValues.toArray(new String[removeValues.size()]));
modifications.add(removeModification);
}
if (addValues.size() > 0) {
Modification addModification = createModification(ModificationType.ADD, attributeName, addValues.toArray(new String[addValues.size()]));
modifications.add(addModification);
}
}
}
}
if (modification != null) {
modifications.add(modification);
}
}
if (modifications.size() > 0) {
boolean result = getOperationService().updateEntry(dn, modifications);
if (!result) {
throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn));
}
}
} catch (ConnectionException ex) {
throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn), ex.getCause());
} catch (Exception ex) {
throw new EntryPersistenceException(String.format("Failed to update entry: %s", dn), ex);
}
}
use of io.jans.orm.model.AttributeDataModification in project jans by JanssenProject.
the class SpannerEntryManager method createModification.
private AttributeDataModification createModification(final AttributeModificationType type, final String attributeName, final Boolean multiValued, final Object[] attributeValues, final Object[] oldAttributeValues) {
String realAttributeName = attributeName;
Object[] realValues = attributeValues;
if (StringHelper.equalsIgnoreCase(SpannerOperationService.USER_PASSWORD, realAttributeName)) {
realValues = getOperationService().createStoragePassword(StringHelper.toStringArray(attributeValues));
}
escapeValues(realValues);
if (AttributeModificationType.REPLACE == type) {
escapeValues(oldAttributeValues);
return new AttributeDataModification(type, new AttributeData(realAttributeName, realValues, multiValued), new AttributeData(realAttributeName, oldAttributeValues, multiValued));
} else {
return new AttributeDataModification(type, new AttributeData(realAttributeName, realValues, multiValued));
}
}
use of io.jans.orm.model.AttributeDataModification 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