/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.syncope.core.provisioning.api; import java.io.Serializable; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.syncope.common.lib.types.ResourceOperation; /** * Encapsulates operations to be performed on various resources. */ public class PropagationByResource implements Serializable { private static final long serialVersionUID = -5699740428104336636L; /** * Resources for creation. */ private final Set<String> toBeCreated; /** * Resources for update. */ private final Set<String> toBeUpdated; /** * Resources for deletion. */ private final Set<String> toBeDeleted; /** * Mapping target resource names to old ConnObjectKeys (when applicable). */ private final Map<String, String> oldConnObjectKeys; /** * Default constructor. */ public PropagationByResource() { toBeCreated = new HashSet<>(); toBeUpdated = new HashSet<>(); toBeDeleted = new HashSet<>(); oldConnObjectKeys = new HashMap<>(); } /** * Avoid potential conflicts by not doing create or update on any resource for which a delete is requested, and by * not doing any create on any resource for which an update is requested. */ public final void purge() { toBeCreated.removeAll(toBeDeleted); toBeCreated.removeAll(toBeUpdated); toBeUpdated.removeAll(toBeDeleted); } /** * Add an element. * * @param type resource operation type * @param resourceKey target resource * @return whether the operation was successful or not */ public final boolean add(final ResourceOperation type, final String resourceKey) { Set<String> set; switch (type) { case CREATE: set = toBeCreated; break; case UPDATE: set = toBeUpdated; break; case DELETE: default: set = toBeDeleted; break; } return set.add(resourceKey); } /** * Add some elements. * * @param type resource operation type * @param resourceKeys target resources * @return whether the operation was successful or not */ public boolean addAll(final ResourceOperation type, final Collection<String> resourceKeys) { Set<String> set; switch (type) { case CREATE: set = toBeCreated; break; case UPDATE: set = toBeUpdated; break; case DELETE: default: set = toBeDeleted; break; } return set.addAll(resourceKeys); } /** * Remove an element. * * @param type resource operation type * @param resourceKey target resource * @return whether the operation was successful or not */ public final boolean remove(final ResourceOperation type, final String resourceKey) { boolean result = false; switch (type) { case CREATE: result = toBeCreated.remove(resourceKey); break; case UPDATE: result = toBeUpdated.remove(resourceKey); break; case DELETE: result = toBeDeleted.remove(resourceKey); break; default: } return result; } /** * Remove some elements. * * @param type resource operation type * @param resourceKeys target resources * @return whether the operation was successful or not */ public boolean removeAll(final ResourceOperation type, final Set<String> resourceKeys) { Set<String> set; switch (type) { case CREATE: set = toBeCreated; break; case UPDATE: set = toBeUpdated; break; case DELETE: default: set = toBeDeleted; break; } return set.removeAll(resourceKeys); } /** * Removes only the resource names in the underlying resource name sets that are contained in the specified * collection. * * @param resourceKeys collection containing resource names to be retained in the underlying resource name sets * @return <tt>true</tt> if the underlying resource name sets changed as a result of the call * @see Collection#removeAll(java.util.Collection) */ public boolean removeAll(final Collection<String> resourceKeys) { return toBeCreated.removeAll(resourceKeys) | toBeUpdated.removeAll(resourceKeys) | toBeDeleted.removeAll(resourceKeys); } /** * Retains only the resource names in the underlying resource name sets that are contained in the specified * collection. * * @param resourceKeys collection containing resource names to be retained in the underlying resource name sets * @return <tt>true</tt> if the underlying resource name sets changed as a result of the call * @see Collection#retainAll(java.util.Collection) */ public boolean retainAll(final Collection<String> resourceKeys) { return toBeCreated.retainAll(resourceKeys) | toBeUpdated.retainAll(resourceKeys) | toBeDeleted.retainAll(resourceKeys); } public boolean contains(final ResourceOperation type, final String resourceKey) { boolean result = false; switch (type) { case CREATE: result = toBeCreated.contains(resourceKey); break; case UPDATE: result = toBeUpdated.contains(resourceKey); break; case DELETE: result = toBeDeleted.contains(resourceKey); break; default: } return result; } /** * Get resources for a given resource operation type. * * @param type resource operation type * @return resource matching the given type */ public final Set<String> get(final ResourceOperation type) { Set<String> result = Collections.<String>emptySet(); switch (type) { case CREATE: result = toBeCreated; break; case UPDATE: result = toBeUpdated; break; case DELETE: result = toBeDeleted; break; default: } return result; } public Map<String, ResourceOperation> asMap() { Map<String, ResourceOperation> result = new HashMap<>(); for (ResourceOperation operation : ResourceOperation.values()) { for (String resourceKey : get(operation)) { result.put(resourceKey, operation); } } return result; } /** * Set resources for a given resource operation type. * * @param type resource operation type * @param resourceKeys to be set */ public final void set(final ResourceOperation type, final Collection<String> resourceKeys) { switch (type) { case CREATE: toBeCreated.clear(); toBeCreated.addAll(resourceKeys); break; case UPDATE: toBeUpdated.clear(); toBeUpdated.addAll(resourceKeys); break; case DELETE: toBeDeleted.clear(); toBeDeleted.addAll(resourceKeys); break; default: } } /** * Merge another resource operation instance into this instance. * * @param propByRes to be merged */ public final void merge(final PropagationByResource propByRes) { if (propByRes != null) { toBeCreated.addAll(propByRes.get(ResourceOperation.CREATE)); toBeUpdated.addAll(propByRes.get(ResourceOperation.UPDATE)); toBeDeleted.addAll(propByRes.get(ResourceOperation.DELETE)); oldConnObjectKeys.putAll(propByRes.getOldConnObjectKeys()); } } /** * Removes all of the operations. */ public void clear() { toBeCreated.clear(); toBeUpdated.clear(); toBeDeleted.clear(); } /** * Whether no operations are present. * * @return true if no operations (create / update / delete) and no old connObjectKeys are present */ public final boolean isEmpty() { return toBeCreated.isEmpty() && toBeUpdated.isEmpty() && toBeDeleted.isEmpty() && oldConnObjectKeys.isEmpty(); } /** * Fetch all old connObjectKeys. * * @return old connObjectKeys; can be empty */ public Map<String, String> getOldConnObjectKeys() { return oldConnObjectKeys; } /** * Fetch old connObjectKey for given resource name. * * @param resourceKey resource name * @return old connObjectKey; can be null */ public String getOldConnObjectKey(final String resourceKey) { return oldConnObjectKeys.get(resourceKey); } /** * Add old ConnObjectKey for a given resource name. * * @param resourceKey resourceKey resource name * @param oldConnObjectKey old ConnObjectKey */ public void addOldConnObjectKey(final String resourceKey, final String oldConnObjectKey) { if (resourceKey != null && oldConnObjectKey != null) { oldConnObjectKeys.put(resourceKey, oldConnObjectKey); } } @Override public String toString() { return "To be Created: " + toBeCreated + ";\n" + "To be Updated: " + toBeUpdated + ";\n" + "To be Deleted: " + toBeDeleted + ";\n" + "Old connObjectKeys: " + oldConnObjectKeys; } }