Search in sources :

Example 11 with AttributeDataModification

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);
    }
}
Also used : Modification(com.unboundid.ldap.sdk.Modification) AttributeDataModification(io.jans.orm.model.AttributeDataModification) ArrayList(java.util.ArrayList) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) MappingException(io.jans.orm.exception.MappingException) ParseException(java.text.ParseException) EntryDeleteException(io.jans.orm.exception.EntryDeleteException) SearchScopeException(io.jans.orm.exception.operation.SearchScopeException) EntryPersistenceException(io.jans.orm.exception.EntryPersistenceException) ConnectionException(io.jans.orm.exception.operation.ConnectionException) SearchException(io.jans.orm.exception.operation.SearchException) AuthenticationException(io.jans.orm.exception.AuthenticationException) Comparator(java.util.Comparator) AttributeDataModification(io.jans.orm.model.AttributeDataModification) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) AttributeData(io.jans.orm.model.AttributeData) ConnectionException(io.jans.orm.exception.operation.ConnectionException)

Example 12 with AttributeDataModification

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));
    }
}
Also used : AttributeDataModification(io.jans.orm.model.AttributeDataModification) AttributeData(io.jans.orm.model.AttributeData)

Example 13 with AttributeDataModification

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);
    }
}
Also used : AttributeModificationType(io.jans.orm.model.AttributeDataModification.AttributeModificationType) WriteBuilder(com.google.cloud.spanner.Mutation.WriteBuilder) Builder(com.google.cloud.spanner.Statement.Builder) ValueWithStructField(io.jans.orm.cloud.spanner.model.ValueWithStructField) StructField(com.google.cloud.spanner.Type.StructField) MessageDigest(java.security.MessageDigest) KeySet(com.google.cloud.spanner.KeySet) TableMapping(io.jans.orm.cloud.spanner.model.TableMapping) LinkedList(java.util.LinkedList) AttributeDataModification(io.jans.orm.model.AttributeDataModification) WriteBuilder(com.google.cloud.spanner.Mutation.WriteBuilder) PersistenceException(io.jans.orm.exception.operation.PersistenceException) Mutation(com.google.cloud.spanner.Mutation) SpannerException(com.google.cloud.spanner.SpannerException) AttributeData(io.jans.orm.model.AttributeData)

Aggregations

AttributeData (io.jans.orm.model.AttributeData)13 AttributeDataModification (io.jans.orm.model.AttributeDataModification)13 MappingException (io.jans.orm.exception.MappingException)5 AttributeModificationType (io.jans.orm.model.AttributeDataModification.AttributeModificationType)5 ArrayList (java.util.ArrayList)5 AuthenticationException (io.jans.orm.exception.AuthenticationException)4 EntryDeleteException (io.jans.orm.exception.EntryDeleteException)4 EntryPersistenceException (io.jans.orm.exception.EntryPersistenceException)4 SearchException (io.jans.orm.exception.operation.SearchException)4 PersistenceException (io.jans.orm.exception.operation.PersistenceException)2 PropertyAnnotation (io.jans.orm.reflect.property.PropertyAnnotation)2 DateTimeParseException (java.time.format.DateTimeParseException)2 LinkedList (java.util.LinkedList)2 JsonObject (com.couchbase.client.java.document.json.JsonObject)1 MutationSpec (com.couchbase.client.java.subdoc.MutationSpec)1 KeySet (com.google.cloud.spanner.KeySet)1 Mutation (com.google.cloud.spanner.Mutation)1 WriteBuilder (com.google.cloud.spanner.Mutation.WriteBuilder)1 SpannerException (com.google.cloud.spanner.SpannerException)1 Builder (com.google.cloud.spanner.Statement.Builder)1