You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/16 09:06:42 UTC
[17/59] [abbrv] [partial] syncope git commit: [SYNCOPE-620]
Re-organization completed
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
new file mode 100644
index 0000000..1c53db6
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AttributableOperations.java
@@ -0,0 +1,508 @@
+/*
+ * 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.common.lib;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.mod.AbstractAttributableMod;
+import org.apache.syncope.common.lib.mod.AbstractSubjectMod;
+import org.apache.syncope.common.lib.mod.AttrMod;
+import org.apache.syncope.common.lib.mod.MembershipMod;
+import org.apache.syncope.common.lib.mod.ReferenceMod;
+import org.apache.syncope.common.lib.mod.RoleMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AbstractAttributableTO;
+import org.apache.syncope.common.lib.to.AbstractSubjectTO;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+
+/**
+ * Utility class for manipulating classes extending AbstractAttributableTO and AbstractAttributableMod.
+ *
+ * @see AbstractAttributableTO
+ * @see AbstractAttributableMod
+ */
+public final class AttributableOperations {
+
+ private AttributableOperations() {
+ // empty constructor for static utility classes
+ }
+
+ private static void populate(final Map<String, AttrTO> updatedAttrs,
+ final Map<String, AttrTO> originalAttrs, final AbstractAttributableMod result) {
+
+ populate(updatedAttrs, originalAttrs, result, false);
+ }
+
+ private static void populate(final Map<String, AttrTO> updatedAttrs,
+ final Map<String, AttrTO> originalAttrs, final AbstractAttributableMod result,
+ final boolean virtuals) {
+
+ for (Map.Entry<String, AttrTO> entry : updatedAttrs.entrySet()) {
+ AttrMod mod = new AttrMod();
+ mod.setSchema(entry.getKey());
+
+ Set<String> updatedValues = new HashSet<String>(entry.getValue().getValues());
+
+ Set<String> originalValues = originalAttrs.containsKey(entry.getKey())
+ ? new HashSet<String>(originalAttrs.get(entry.getKey()).getValues())
+ : Collections.<String>emptySet();
+
+ if (!originalAttrs.containsKey(entry.getKey())) {
+ // SYNCOPE-459: take care of user virtual attributes without any value
+ updatedValues.remove("");
+ mod.getValuesToBeAdded().addAll(new ArrayList<String>(updatedValues));
+
+ if (virtuals) {
+ result.getVirAttrsToUpdate().add(mod);
+ } else {
+ result.getPlainAttrsToUpdate().add(mod);
+ }
+ } else if (!updatedValues.equals(originalValues)) {
+ // avoid unwanted inputs
+ updatedValues.remove("");
+ if (!entry.getValue().isReadonly()) {
+ mod.getValuesToBeAdded().addAll(updatedValues);
+
+ if (!mod.isEmpty()) {
+ if (virtuals) {
+ result.getVirAttrsToRemove().add(mod.getSchema());
+ } else {
+ result.getPlainAttrsToRemove().add(mod.getSchema());
+ }
+ }
+ }
+
+ mod.getValuesToBeRemoved().addAll(originalValues);
+
+ if (!mod.isEmpty()) {
+ if (virtuals) {
+ result.getVirAttrsToUpdate().add(mod);
+ } else {
+ result.getPlainAttrsToUpdate().add(mod);
+ }
+ }
+ }
+ }
+ }
+
+ private static void diff(
+ final AbstractAttributableTO updated,
+ final AbstractAttributableTO original,
+ final AbstractAttributableMod result,
+ final boolean incremental) {
+
+ // 1. check same id
+ if (updated.getKey() != original.getKey()) {
+ throw new IllegalArgumentException("AttributableTO's id must be the same");
+ }
+ result.setKey(updated.getKey());
+
+ // 2. attributes
+ Map<String, AttrTO> updatedAttrs = new HashMap<>(updated.getPlainAttrMap());
+ Map<String, AttrTO> originalAttrs = new HashMap<>(original.getPlainAttrMap());
+
+ Set<String> originalAttrNames = new HashSet<>(originalAttrs.keySet());
+ originalAttrNames.removeAll(updatedAttrs.keySet());
+
+ if (!incremental) {
+ result.getPlainAttrsToRemove().clear();
+ result.getPlainAttrsToRemove().addAll(originalAttrNames);
+ }
+
+ Set<String> emptyUpdatedAttrs = new HashSet<>();
+ for (Map.Entry<String, AttrTO> entry : updatedAttrs.entrySet()) {
+ if (entry.getValue().getValues() == null || entry.getValue().getValues().isEmpty()) {
+
+ emptyUpdatedAttrs.add(entry.getKey());
+ }
+ }
+ for (String emptyUpdatedAttr : emptyUpdatedAttrs) {
+ updatedAttrs.remove(emptyUpdatedAttr);
+ result.getPlainAttrsToRemove().add(emptyUpdatedAttr);
+ }
+
+ populate(updatedAttrs, originalAttrs, result);
+
+ // 3. derived attributes
+ updatedAttrs = updated.getDerAttrMap();
+ originalAttrs = original.getDerAttrMap();
+
+ originalAttrNames = new HashSet<>(originalAttrs.keySet());
+ originalAttrNames.removeAll(updatedAttrs.keySet());
+
+ if (!incremental) {
+ result.getDerAttrsToRemove().clear();
+ result.getDerAttrsToRemove().addAll(originalAttrNames);
+ }
+
+ Set<String> updatedAttrNames = new HashSet<>(updatedAttrs.keySet());
+ updatedAttrNames.removeAll(originalAttrs.keySet());
+ result.getDerAttrsToAdd().clear();
+ result.getDerAttrsToAdd().addAll(updatedAttrNames);
+
+ // 4. virtual attributes
+ updatedAttrs = updated.getVirAttrMap();
+ originalAttrs = original.getVirAttrMap();
+
+ originalAttrNames = new HashSet<>(originalAttrs.keySet());
+ originalAttrNames.removeAll(updatedAttrs.keySet());
+
+ if (!incremental) {
+ result.getVirAttrsToRemove().clear();
+ result.getVirAttrsToRemove().addAll(originalAttrNames);
+ }
+
+ populate(updatedAttrs, originalAttrs, result, true);
+
+ // 5. resources
+ if (original instanceof AbstractSubjectTO && updated instanceof AbstractSubjectTO
+ && result instanceof AbstractSubjectMod) {
+
+ Set<String> updatedRes = new HashSet<>(((AbstractSubjectTO) updated).getResources());
+ Set<String> originalRes = new HashSet<>(((AbstractSubjectTO) original).getResources());
+
+ updatedRes.removeAll(originalRes);
+ ((AbstractSubjectMod) result).getResourcesToAdd().clear();
+ ((AbstractSubjectMod) result).getResourcesToAdd().addAll(updatedRes);
+
+ originalRes.removeAll(((AbstractSubjectTO) updated).getResources());
+
+ if (!incremental) {
+ ((AbstractSubjectMod) result).getResourcesToRemove().clear();
+ ((AbstractSubjectMod) result).getResourcesToRemove().addAll(originalRes);
+ }
+ }
+ }
+
+ /**
+ * Calculate modifications needed by first in order to be equal to second.
+ *
+ * @param updated updated UserTO
+ * @param original original UserTO
+ * @return UserMod containing differences
+ */
+ public static UserMod diff(final UserTO updated, final UserTO original) {
+ return diff(updated, original, false);
+ }
+
+ /**
+ * Calculate modifications needed by first in order to be equal to second.
+ *
+ * @param updated updated UserTO
+ * @param original original UserTO
+ * @param incremental perform incremental diff (without removing existing info)
+ * @return UserMod containing differences
+ */
+ public static UserMod diff(final UserTO updated, final UserTO original, final boolean incremental) {
+ UserMod result = new UserMod();
+
+ diff(updated, original, result, incremental);
+
+ // 1. password
+ if (updated.getPassword() != null && (original.getPassword() == null
+ || !original.getPassword().equals(updated.getPassword()))) {
+
+ result.setPassword(updated.getPassword());
+ }
+
+ // 2. username
+ if (original.getUsername() != null && !original.getUsername().equals(updated.getUsername())) {
+ result.setUsername(updated.getUsername());
+ }
+
+ // 3. security question / answer
+ if (updated.getSecurityQuestion() == null) {
+ result.setSecurityQuestion(null);
+ result.setSecurityAnswer(null);
+ } else if (!updated.getSecurityQuestion().equals(original.getSecurityQuestion())
+ || StringUtils.isNotBlank(updated.getSecurityAnswer())) {
+
+ result.setSecurityQuestion(updated.getSecurityQuestion());
+ result.setSecurityAnswer(updated.getSecurityAnswer());
+ }
+
+ // 4. memberships
+ Map<Long, MembershipTO> updatedMembs = updated.getMembershipMap();
+ Map<Long, MembershipTO> originalMembs = original.getMembershipMap();
+
+ for (Map.Entry<Long, MembershipTO> entry : updatedMembs.entrySet()) {
+ MembershipMod membMod = new MembershipMod();
+ membMod.setRole(entry.getValue().getRoleId());
+
+ if (originalMembs.containsKey(entry.getKey())) {
+ // if memberships are actually same, just make the isEmpty() call below succeed
+ if (entry.getValue().equals(originalMembs.get(entry.getKey()))) {
+ membMod.setRole(0);
+ } else {
+ diff(entry.getValue(), originalMembs.get(entry.getKey()), membMod, false);
+ }
+ } else {
+ for (AttrTO attr : entry.getValue().getPlainAttrs()) {
+ AttrMod attrMod = new AttrMod();
+ attrMod.setSchema(attr.getSchema());
+ attrMod.getValuesToBeAdded().addAll(attr.getValues());
+
+ if (!attrMod.isEmpty()) {
+ membMod.getPlainAttrsToUpdate().add(attrMod);
+ membMod.getPlainAttrsToRemove().add(attrMod.getSchema());
+ }
+ }
+ for (AttrTO attr : entry.getValue().getDerAttrs()) {
+ membMod.getDerAttrsToAdd().add(attr.getSchema());
+ }
+ for (AttrTO attr : entry.getValue().getVirAttrs()) {
+ AttrMod attrMod = new AttrMod();
+ attrMod.setSchema(attr.getSchema());
+ attrMod.getValuesToBeAdded().addAll(attr.getValues());
+
+ if (!attrMod.isEmpty()) {
+ membMod.getVirAttrsToUpdate().add(attrMod);
+ membMod.getPlainAttrsToRemove().add(attrMod.getSchema());
+ }
+ }
+ }
+
+ if (!membMod.isEmpty()) {
+ result.getMembershipsToAdd().add(membMod);
+ }
+ }
+
+ if (!incremental) {
+ Set<Long> originalRoles = new HashSet<>(originalMembs.keySet());
+ originalRoles.removeAll(updatedMembs.keySet());
+ for (Long roleId : originalRoles) {
+ result.getMembershipsToRemove().add(originalMembs.get(roleId).getKey());
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Calculate modifications needed by first in order to be equal to second.
+ *
+ * @param updated updated RoleTO
+ * @param original original RoleTO
+ * @return RoleMod containing differences
+ */
+ public static RoleMod diff(final RoleTO updated, final RoleTO original) {
+ return diff(updated, original, false);
+ }
+
+ /**
+ * Calculate modifications needed by first in order to be equal to second.
+ *
+ * @param updated updated RoleTO
+ * @param original original RoleTO
+ * @param incremental perform incremental diff (without removing existing info)
+ * @return RoleMod containing differences
+ */
+ public static RoleMod diff(final RoleTO updated, final RoleTO original, final boolean incremental) {
+ RoleMod result = new RoleMod();
+
+ diff(updated, original, result, incremental);
+
+ // 1. inheritance
+ result.setInheritOwner(updated.isInheritOwner());
+ result.setInheritTemplates(updated.isInheritTemplates());
+ result.setInheritAccountPolicy(updated.isInheritAccountPolicy());
+ result.setInheritPasswordPolicy(updated.isInheritPasswordPolicy());
+ result.setInheritPlainAttrs(updated.isInheritPlainAttrs());
+ result.setInheritDerAttrs(updated.isInheritDerAttrs());
+ result.setInheritVirAttrs(updated.isInheritVirAttrs());
+
+ // 2. policies
+ result.setAccountPolicy(new ReferenceMod(updated.getAccountPolicy()));
+ result.setPasswordPolicy(new ReferenceMod(updated.getPasswordPolicy()));
+
+ // 3. name
+ if (!original.getName().equals(updated.getName())) {
+ result.setName(updated.getName());
+ }
+
+ // 4. entitlements
+ Set<String> updatedEnts = new HashSet<>(updated.getEntitlements());
+ Set<String> originalEnts = new HashSet<>(original.getEntitlements());
+ if (updatedEnts.equals(originalEnts)) {
+ result.setModEntitlements(false);
+ result.getEntitlements().clear();
+ } else {
+ result.setModEntitlements(true);
+ result.getEntitlements().addAll(updated.getEntitlements());
+ }
+
+ // 5. templates
+ Set<String> updatedTemplates = new HashSet<>(updated.getRPlainAttrTemplates());
+ Set<String> originalTemplates = new HashSet<>(original.getRPlainAttrTemplates());
+ if (updatedTemplates.equals(originalTemplates)) {
+ result.setModRAttrTemplates(false);
+ result.getRPlainAttrTemplates().clear();
+ } else {
+ result.setModRAttrTemplates(true);
+ result.getRPlainAttrTemplates().addAll(updated.getRPlainAttrTemplates());
+ }
+ updatedTemplates = new HashSet<>(updated.getRDerAttrTemplates());
+ originalTemplates = new HashSet<>(original.getRDerAttrTemplates());
+ if (updatedTemplates.equals(originalTemplates)) {
+ result.setModRDerAttrTemplates(false);
+ result.getRDerAttrTemplates().clear();
+ } else {
+ result.setModRDerAttrTemplates(true);
+ result.getRDerAttrTemplates().addAll(updated.getRDerAttrTemplates());
+ }
+ updatedTemplates = new HashSet<>(updated.getRVirAttrTemplates());
+ originalTemplates = new HashSet<>(original.getRVirAttrTemplates());
+ if (updatedTemplates.equals(originalTemplates)) {
+ result.setModRVirAttrTemplates(false);
+ result.getRVirAttrTemplates().clear();
+ } else {
+ result.setModRVirAttrTemplates(true);
+ result.getRVirAttrTemplates().addAll(updated.getRVirAttrTemplates());
+ }
+ updatedTemplates = new HashSet<>(updated.getMPlainAttrTemplates());
+ originalTemplates = new HashSet<>(original.getMPlainAttrTemplates());
+ if (updatedTemplates.equals(originalTemplates)) {
+ result.setModMAttrTemplates(false);
+ result.getMPlainAttrTemplates().clear();
+ } else {
+ result.setModMAttrTemplates(true);
+ result.getMPlainAttrTemplates().addAll(updated.getMPlainAttrTemplates());
+ }
+ updatedTemplates = new HashSet<>(updated.getMDerAttrTemplates());
+ originalTemplates = new HashSet<>(original.getMDerAttrTemplates());
+ if (updatedTemplates.equals(originalTemplates)) {
+ result.setModMDerAttrTemplates(false);
+ result.getMDerAttrTemplates().clear();
+ } else {
+ result.setModMDerAttrTemplates(true);
+ result.getMDerAttrTemplates().addAll(updated.getMDerAttrTemplates());
+ }
+ updatedTemplates = new HashSet<>(updated.getMVirAttrTemplates());
+ originalTemplates = new HashSet<>(original.getMVirAttrTemplates());
+ if (updatedTemplates.equals(originalTemplates)) {
+ result.setModMVirAttrTemplates(false);
+ result.getMVirAttrTemplates().clear();
+ } else {
+ result.setModMVirAttrTemplates(true);
+ result.getMVirAttrTemplates().addAll(updated.getMVirAttrTemplates());
+ }
+
+ // 6. owner
+ result.setUserOwner(new ReferenceMod(updated.getUserOwner()));
+ result.setRoleOwner(new ReferenceMod(updated.getRoleOwner()));
+
+ return result;
+ }
+
+ private static List<AttrTO> getUpdateValues(final Map<String, AttrTO> attrs,
+ final Set<String> attrsToBeRemoved, final Set<AttrMod> attrsToBeUpdated) {
+
+ Map<String, AttrTO> rwattrs = new HashMap<>(attrs);
+ for (String attrName : attrsToBeRemoved) {
+ rwattrs.remove(attrName);
+ }
+ for (AttrMod attrMod : attrsToBeUpdated) {
+ if (rwattrs.containsKey(attrMod.getSchema())) {
+ AttrTO attrTO = rwattrs.get(attrMod.getSchema());
+ attrTO.getValues().removeAll(attrMod.getValuesToBeRemoved());
+ attrTO.getValues().addAll(attrMod.getValuesToBeAdded());
+ } else {
+ AttrTO attrTO = new AttrTO();
+ attrTO.setSchema(attrMod.getSchema());
+ attrTO.getValues().addAll(attrMod.getValuesToBeAdded());
+
+ rwattrs.put(attrMod.getSchema(), attrTO);
+ }
+ }
+
+ return new ArrayList<>(rwattrs.values());
+ }
+
+ private static <T extends AbstractAttributableTO, K extends AbstractAttributableMod> void apply(final T to,
+ final K mod, final T result) {
+
+ // 1. attributes
+ result.getPlainAttrs().addAll(getUpdateValues(to.getPlainAttrMap(),
+ mod.getPlainAttrsToRemove(), mod.getPlainAttrsToUpdate()));
+
+ // 2. derived attributes
+ Map<String, AttrTO> attrs = to.getDerAttrMap();
+ for (String attrName : mod.getDerAttrsToRemove()) {
+ attrs.remove(attrName);
+ }
+ for (String attrName : mod.getDerAttrsToAdd()) {
+ AttrTO attrTO = new AttrTO();
+ attrTO.setSchema(attrName);
+
+ attrs.put(attrName, attrTO);
+ }
+ result.getDerAttrs().addAll(attrs.values());
+
+ // 3. virtual attributes
+ result.getVirAttrs().addAll(getUpdateValues(to.getVirAttrMap(),
+ mod.getVirAttrsToRemove(), mod.getVirAttrsToUpdate()));
+
+ // 4. resources
+ if (result instanceof AbstractSubjectTO && mod instanceof AbstractSubjectMod) {
+ ((AbstractSubjectTO) result).getResources().removeAll(((AbstractSubjectMod) mod).getResourcesToRemove());
+ ((AbstractSubjectTO) result).getResources().addAll(((AbstractSubjectMod) mod).getResourcesToAdd());
+ }
+ }
+
+ public static UserTO apply(final UserTO userTO, final UserMod userMod) {
+ // 1. check same id
+ if (userTO.getKey() != userMod.getKey()) {
+ throw new IllegalArgumentException("UserTO and UserMod ids must be the same");
+ }
+
+ UserTO result = SerializationUtils.clone(userTO);
+ apply(userTO, userMod, result);
+
+ // 1. password
+ result.setPassword(userMod.getPassword());
+
+ // 2. username
+ if (userMod.getUsername() != null) {
+ result.setUsername(userMod.getUsername());
+ }
+ // 3. memberships
+ Map<Long, MembershipTO> membs = result.getMembershipMap();
+ for (Long membId : userMod.getMembershipsToRemove()) {
+ result.getMemberships().remove(membs.get(membId));
+ }
+ for (MembershipMod membMod : userMod.getMembershipsToAdd()) {
+ MembershipTO membTO = new MembershipTO();
+ membTO.setRoleId(membMod.getRole());
+
+ apply(membTO, membMod, membTO);
+ }
+
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
new file mode 100644
index 0000000..7322cc8
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientCompositeException.java
@@ -0,0 +1,96 @@
+/*
+ * 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.common.lib;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+
+public class SyncopeClientCompositeException extends SyncopeClientException {
+
+ private static final long serialVersionUID = 7882118041134372129L;
+
+ private final Set<SyncopeClientException> exceptions = new HashSet<>();
+
+ protected SyncopeClientCompositeException() {
+ super(ClientExceptionType.Composite);
+ }
+
+ public boolean hasExceptions() {
+ return !exceptions.isEmpty();
+ }
+
+ public boolean hasException(final ClientExceptionType exceptionType) {
+ return getException(exceptionType) != null;
+ }
+
+ public SyncopeClientException getException(final ClientExceptionType exceptionType) {
+ boolean found = false;
+ SyncopeClientException syncopeClientException = null;
+ for (Iterator<SyncopeClientException> itor = exceptions.iterator(); itor.hasNext() && !found;) {
+ syncopeClientException = itor.next();
+ if (syncopeClientException.getType().equals(exceptionType)) {
+ found = true;
+ }
+ }
+
+ return found
+ ? syncopeClientException
+ : null;
+ }
+
+ public Set<SyncopeClientException> getExceptions() {
+ return exceptions;
+ }
+
+ public boolean addException(final SyncopeClientException exception) {
+ if (exception.getType() == null) {
+ throw new IllegalArgumentException(exception + " does not have the right "
+ + ClientExceptionType.class.getName() + " set");
+ }
+
+ return exceptions.add(exception);
+ }
+
+ @Override
+ public String getMessage() {
+ StringBuilder message = new StringBuilder();
+
+ message.append("{");
+ Iterator<SyncopeClientException> iter = getExceptions().iterator();
+ while (iter.hasNext()) {
+ SyncopeClientException e = iter.next();
+ message.append("[");
+ message.append(e.getMessage());
+ message.append("]");
+ if (iter.hasNext()) {
+ message.append(", ");
+ }
+ }
+ message.append("}");
+
+ return message.toString();
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return getMessage();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
new file mode 100644
index 0000000..2243835
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeClientException.java
@@ -0,0 +1,97 @@
+/*
+ * 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.common.lib;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+
+public class SyncopeClientException extends RuntimeException {
+
+ private static final long serialVersionUID = 3380920886511913475L;
+
+ private ClientExceptionType type;
+
+ private final List<String> elements = new ArrayList<>();
+
+ public static SyncopeClientException build(final ClientExceptionType type) {
+ if (type == ClientExceptionType.Composite) {
+ throw new IllegalArgumentException("Composite exceptions must be obtained via buildComposite()");
+ }
+ return new SyncopeClientException(type);
+ }
+
+ public static SyncopeClientCompositeException buildComposite() {
+ return new SyncopeClientCompositeException();
+ }
+
+ protected SyncopeClientException(final ClientExceptionType type) {
+ super();
+ setType(type);
+ }
+
+ public boolean isComposite() {
+ return getType() == ClientExceptionType.Composite;
+ }
+
+ public SyncopeClientCompositeException asComposite() {
+ if (!isComposite()) {
+ throw new IllegalArgumentException("This is not a composite exception");
+ }
+
+ return (SyncopeClientCompositeException) this;
+ }
+
+ public ClientExceptionType getType() {
+ return type;
+ }
+
+ public final void setType(final ClientExceptionType type) {
+ this.type = type;
+ }
+
+ public List<String> getElements() {
+ return elements;
+ }
+
+ public boolean isEmpty() {
+ return elements.isEmpty();
+ }
+
+ public int size() {
+ return elements.size();
+ }
+
+ @Override
+ public String getMessage() {
+ StringBuilder message = new StringBuilder();
+
+ message.append(getType());
+ message.append(" ");
+ message.append(getElements());
+
+ return message.toString();
+ }
+
+ @Override
+ public String getLocalizedMessage() {
+ return getMessage();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
new file mode 100644
index 0000000..817b00d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/SyncopeConstants.java
@@ -0,0 +1,52 @@
+/*
+ * 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.common.lib;
+
+import java.util.regex.Pattern;
+
+public class SyncopeConstants {
+
+ public static final String NAMESPACE = "http://syncope.apache.org/2.0";
+
+ public static final String UNAUTHENTICATED = "unauthenticated";
+
+ public static final String ANONYMOUS_ENTITLEMENT = "anonymous";
+
+ public static final String ENUM_VALUES_SEPARATOR = ";";
+
+ public static final String[] DATE_PATTERNS = {
+ "yyyy-MM-dd'T'HH:mm:ssZ",
+ "EEE, dd MMM yyyy HH:mm:ss z",
+ "yyyy-MM-dd'T'HH:mm:ssz",
+ "yyyy-MM-dd HH:mm:ss",
+ "yyyy-MM-dd HH:mm:ss.S", // explicitly added to import date into MySql repository
+ "yyyy-MM-dd" };
+
+ public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssZ";
+
+ public static final String DEFAULT_ENCODING = "UTF-8";
+
+ public static final String ROOT_LOGGER = "ROOT";
+
+ public static final Pattern EMAIL_PATTERN = Pattern.compile(
+ "^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*"
+ + "@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$",
+ Pattern.CASE_INSENSITIVE);
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java
new file mode 100644
index 0000000..07528ea
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/ClassList.java
@@ -0,0 +1,26 @@
+/*
+ * 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.common.lib.annotation;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Retention(RUNTIME)
+public @interface ClassList {
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
new file mode 100644
index 0000000..2c1c980
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/FormAttributeField.java
@@ -0,0 +1,36 @@
+/*
+ * 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.common.lib.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.apache.syncope.common.lib.types.IntMappingType;
+
+@Target({ ElementType.FIELD })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface FormAttributeField {
+
+ boolean userSearch() default false;
+
+ boolean roleSearch() default false;
+
+ IntMappingType schema() default IntMappingType.UserPlainSchema;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java
new file mode 100644
index 0000000..7469731
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/annotation/SchemaList.java
@@ -0,0 +1,28 @@
+/*
+ * 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.common.lib.annotation;
+
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Retention(RUNTIME)
+public @interface SchemaList {
+
+ boolean extended() default false;
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
new file mode 100644
index 0000000..aa5d442
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractAttributableMod.java
@@ -0,0 +1,111 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+/**
+ * Abstract base class for objects that can have attributes removed, added or updated.
+ *
+ * Attributes can be regular attributes, derived attributes, virtual attributes and resources.
+ */
+@XmlType
+public abstract class AbstractAttributableMod extends AbstractBaseBean {
+
+ private static final long serialVersionUID = 3241118574016303198L;
+
+ protected long key;
+
+ protected final Set<AttrMod> plainAttrsToUpdate = new HashSet<>();
+
+ protected final Set<String> plainAttrsToRemove = new HashSet<>();
+
+ protected final Set<String> derAttrsToAdd = new HashSet<>();
+
+ protected final Set<String> derAttrsToRemove = new HashSet<>();
+
+ protected final Set<AttrMod> virAttrsToUpdate = new HashSet<>();
+
+ protected final Set<String> virAttrsToRemove = new HashSet<>();
+
+ public long getKey() {
+ return key;
+ }
+
+ public void setKey(final long key) {
+ this.key = key;
+ }
+
+ @XmlElementWrapper(name = "plainAttrsToRemove")
+ @XmlElement(name = "attribute")
+ @JsonProperty("plainAttrsToRemove")
+ public Set<String> getPlainAttrsToRemove() {
+ return plainAttrsToRemove;
+ }
+
+ @XmlElementWrapper(name = "plainAttrsToUpdate")
+ @XmlElement(name = "attributeMod")
+ @JsonProperty("plainAttrsToUpdate")
+ public Set<AttrMod> getPlainAttrsToUpdate() {
+ return plainAttrsToUpdate;
+ }
+
+ @XmlElementWrapper(name = "derAttrsToAdd")
+ @XmlElement(name = "attribute")
+ @JsonProperty("derAttrsToAdd")
+ public Set<String> getDerAttrsToAdd() {
+ return derAttrsToAdd;
+ }
+
+ @XmlElementWrapper(name = "derAttrsToRemove")
+ @XmlElement(name = "attribute")
+ @JsonProperty("derAttrsToRemove")
+ public Set<String> getDerAttrsToRemove() {
+ return derAttrsToRemove;
+ }
+
+ @XmlElementWrapper(name = "virAttrsToRemove")
+ @XmlElement(name = "attribute")
+ @JsonProperty("virAttrsToRemove")
+ public Set<String> getVirAttrsToRemove() {
+ return virAttrsToRemove;
+ }
+
+ @XmlElementWrapper(name = "virAttrsToUpdate")
+ @XmlElement(name = "attribute")
+ @JsonProperty("virAttrsToUpdate")
+ public Set<AttrMod> getVirAttrsToUpdate() {
+ return virAttrsToUpdate;
+ }
+
+ /**
+ * @return true is all backing Sets are empty.
+ */
+ public boolean isEmpty() {
+ return plainAttrsToUpdate.isEmpty() && plainAttrsToRemove.isEmpty()
+ && derAttrsToAdd.isEmpty() && derAttrsToRemove.isEmpty()
+ && virAttrsToUpdate.isEmpty() && virAttrsToRemove.isEmpty();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java
new file mode 100644
index 0000000..96e2a64
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AbstractSubjectMod.java
@@ -0,0 +1,56 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlType
+public abstract class AbstractSubjectMod extends AbstractAttributableMod {
+
+ private static final long serialVersionUID = -6404459635536484024L;
+
+ protected final Set<String> resourcesToAdd = new HashSet<>();
+
+ protected final Set<String> resourcesToRemove = new HashSet<>();
+
+ @XmlElementWrapper(name = "resourcesToAdd")
+ @XmlElement(name = "resource")
+ @JsonProperty("resourcesToAdd")
+ public Set<String> getResourcesToAdd() {
+ return resourcesToAdd;
+ }
+
+ @XmlElementWrapper(name = "resourcesToRemove")
+ @XmlElement(name = "resource")
+ @JsonProperty("resourcesToRemove")
+ public Set<String> getResourcesToRemove() {
+ return resourcesToRemove;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && resourcesToAdd.isEmpty() && resourcesToRemove.isEmpty();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AttrMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AttrMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AttrMod.java
new file mode 100644
index 0000000..b0cee5b
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/AttrMod.java
@@ -0,0 +1,76 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement
+@XmlType
+public class AttrMod extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -913573979137431406L;
+
+ private String schema;
+
+ private List<String> valuesToBeAdded;
+
+ private List<String> valuesToBeRemoved;
+
+ public AttrMod() {
+ super();
+
+ valuesToBeAdded = new ArrayList<>();
+ valuesToBeRemoved = new ArrayList<>();
+ }
+
+ public String getSchema() {
+ return schema;
+ }
+
+ public void setSchema(final String schema) {
+ this.schema = schema;
+ }
+
+ @XmlElementWrapper(name = "valuesToBeAdded")
+ @XmlElement(name = "value")
+ @JsonProperty("valuesToBeAdded")
+ public List<String> getValuesToBeAdded() {
+ return valuesToBeAdded;
+ }
+
+ @XmlElementWrapper(name = "valuesToBeRemoved")
+ @XmlElement(name = "value")
+ @JsonProperty("valuesToBeRemoved")
+ public List<String> getValuesToBeRemoved() {
+ return valuesToBeRemoved;
+ }
+
+ @JsonIgnore
+ public boolean isEmpty() {
+ return valuesToBeAdded.isEmpty() && valuesToBeRemoved.isEmpty();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java
new file mode 100644
index 0000000..bdcfcbf
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/MembershipMod.java
@@ -0,0 +1,46 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement
+@XmlType
+public class MembershipMod extends AbstractAttributableMod {
+
+ private static final long serialVersionUID = 2511869129977331525L;
+
+ private long role;
+
+ public long getRole() {
+ return role;
+ }
+
+ public void setRole(final long role) {
+ this.role = role;
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && role == 0;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ReferenceMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ReferenceMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ReferenceMod.java
new file mode 100644
index 0000000..e8356c2
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ReferenceMod.java
@@ -0,0 +1,53 @@
+/*
+ * 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.common.lib.mod;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+/**
+ * This class is used to specify the willing to modify an external reference id. Use 'null' ReferenceMod to keep the
+ * current reference id; use a ReferenceMod with a null id to try to reset the reference id; use a ReferenceMod with a
+ * not null id to specify a new reference id.
+ */
+@XmlRootElement(name = "referenceMod")
+@XmlType
+public class ReferenceMod extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -4188817853738067677L;
+
+ private Long key;
+
+ public ReferenceMod() {
+ this.key = null;
+ }
+
+ public ReferenceMod(final Long key) {
+ this.key = key;
+ }
+
+ public Long getKey() {
+ return key;
+ }
+
+ public void setKey(final Long key) {
+ this.key = key;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
new file mode 100644
index 0000000..6312349
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/ResourceAssociationMod.java
@@ -0,0 +1,80 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+
+/**
+ * This class is used to specify the willing to create associations between user and external references.
+ * Password can be provided if required by an assign or provisioning operation.
+ *
+ * @see org.apache.syncope.common.types.ResourceAssociationActionType
+ */
+@XmlRootElement(name = "resourceAssociationMod")
+@XmlType
+public class ResourceAssociationMod extends AbstractBaseBean {
+
+ private static final long serialVersionUID = -4188817853738067678L;
+
+ /**
+ * Target external resources.
+ */
+ private final List<ResourceName> targetResources = new ArrayList<ResourceName>();
+
+ /**
+ * Indicate the willing to change password on target external resources.
+ */
+ private boolean changePwd;
+
+ /**
+ * Indicate the new password to be provisioned on target external resources.
+ */
+ private String password;
+
+ @XmlElementWrapper(name = "resources")
+ @XmlElement(name = "resource")
+ @JsonProperty("resources")
+ public List<ResourceName> getTargetResources() {
+ return targetResources;
+ }
+
+ public boolean isChangePwd() {
+ return changePwd;
+ }
+
+ public void setChangePwd(boolean changePwd) {
+ this.changePwd = changePwd;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/RoleMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/RoleMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/RoleMod.java
new file mode 100644
index 0000000..b1b8f4f
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/RoleMod.java
@@ -0,0 +1,300 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "roleMod")
+@XmlType
+public class RoleMod extends AbstractSubjectMod {
+
+ private static final long serialVersionUID = 7455805264680210747L;
+
+ private String name;
+
+ private ReferenceMod userOwner;
+
+ private ReferenceMod roleOwner;
+
+ private Boolean inheritOwner;
+
+ private Boolean inheritTemplates;
+
+ private Boolean inheritPlainAttrs;
+
+ private Boolean inheritDerAttrs;
+
+ private Boolean inheritVirAttrs;
+
+ private Boolean inheritAccountPolicy;
+
+ private Boolean inheritPasswordPolicy;
+
+ private boolean modEntitlements;
+
+ private final List<String> entitlements = new ArrayList<>();
+
+ private boolean modRAttrTemplates;
+
+ private final List<String> rPlainAttrTemplates = new ArrayList<>();
+
+ private boolean modRDerAttrTemplates;
+
+ private final List<String> rDerAttrTemplates = new ArrayList<>();
+
+ private boolean modRVirAttrTemplates;
+
+ private final List<String> rVirAttrTemplates = new ArrayList<>();
+
+ private boolean modMAttrTemplates;
+
+ private final List<String> mPlainAttrTemplates = new ArrayList<>();
+
+ private boolean modMDerAttrTemplates;
+
+ private final List<String> mDerAttrTemplates = new ArrayList<>();
+
+ private boolean modMVirAttrTemplates;
+
+ private final List<String> mVirAttrTemplates = new ArrayList<>();
+
+ private ReferenceMod passwordPolicy;
+
+ private ReferenceMod accountPolicy;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public ReferenceMod getUserOwner() {
+ return userOwner;
+ }
+
+ public void setUserOwner(final ReferenceMod userOwner) {
+ this.userOwner = userOwner;
+ }
+
+ public ReferenceMod getRoleOwner() {
+ return roleOwner;
+ }
+
+ public void setRoleOwner(final ReferenceMod roleOwner) {
+ this.roleOwner = roleOwner;
+ }
+
+ public Boolean getInheritOwner() {
+ return inheritOwner;
+ }
+
+ public void setInheritOwner(final Boolean inheritOwner) {
+ this.inheritOwner = inheritOwner;
+ }
+
+ public Boolean getInheritTemplates() {
+ return inheritTemplates;
+ }
+
+ public void setInheritTemplates(final Boolean inheritTemplates) {
+ this.inheritTemplates = inheritTemplates;
+ }
+
+ public Boolean getInheritPlainAttrs() {
+ return inheritPlainAttrs;
+ }
+
+ public void setInheritPlainAttrs(final Boolean inheritAttrs) {
+ this.inheritPlainAttrs = inheritAttrs;
+ }
+
+ public Boolean getInheritDerAttrs() {
+ return inheritDerAttrs;
+ }
+
+ public void setInheritDerAttrs(final Boolean inheritDerAttrs) {
+ this.inheritDerAttrs = inheritDerAttrs;
+ }
+
+ public Boolean getInheritVirAttrs() {
+ return inheritVirAttrs;
+ }
+
+ public void setInheritVirAttrs(final Boolean inheritVirAttrs) {
+ this.inheritVirAttrs = inheritVirAttrs;
+ }
+
+ public boolean isModEntitlements() {
+ return modEntitlements;
+ }
+
+ public void setModEntitlements(final boolean modEntitlements) {
+ this.modEntitlements = modEntitlements;
+ }
+
+ @XmlElementWrapper(name = "entitlements")
+ @XmlElement(name = "entitlement")
+ @JsonProperty("entitlements")
+ public List<String> getEntitlements() {
+ return entitlements;
+ }
+
+ public boolean isModRAttrTemplates() {
+ return modRAttrTemplates;
+ }
+
+ public void setModRAttrTemplates(final boolean modRAttrTemplates) {
+ this.modRAttrTemplates = modRAttrTemplates;
+ }
+
+ @XmlElementWrapper(name = "rPlainAttrTemplates")
+ @XmlElement(name = "rAttrTemplate")
+ @JsonProperty("rPlainAttrTemplates")
+ public List<String> getRPlainAttrTemplates() {
+ return rPlainAttrTemplates;
+ }
+
+ public boolean isModRDerAttrTemplates() {
+ return modRDerAttrTemplates;
+ }
+
+ public void setModRDerAttrTemplates(final boolean modRDerAttrTemplates) {
+ this.modRDerAttrTemplates = modRDerAttrTemplates;
+ }
+
+ @XmlElementWrapper(name = "rDerAttrTemplates")
+ @XmlElement(name = "rDerAttrTemplate")
+ @JsonProperty("rDerAttrTemplates")
+ public List<String> getRDerAttrTemplates() {
+ return rDerAttrTemplates;
+ }
+
+ public boolean isModRVirAttrTemplates() {
+ return modRVirAttrTemplates;
+ }
+
+ public void setModRVirAttrTemplates(final boolean modRVirAttrTemplates) {
+ this.modRVirAttrTemplates = modRVirAttrTemplates;
+ }
+
+ @XmlElementWrapper(name = "rVirAttrTemplates")
+ @XmlElement(name = "rVirAttrTemplate")
+ @JsonProperty("rVirAttrTemplates")
+ public List<String> getRVirAttrTemplates() {
+ return rVirAttrTemplates;
+ }
+
+ public boolean isModMAttrTemplates() {
+ return modMAttrTemplates;
+ }
+
+ public void setModMAttrTemplates(final boolean modMAttrTemplates) {
+ this.modMAttrTemplates = modMAttrTemplates;
+ }
+
+ @XmlElementWrapper(name = "mPlainAttrTemplates")
+ @XmlElement(name = "mAttrTemplate")
+ @JsonProperty("mPlainAttrTemplates")
+ public List<String> getMPlainAttrTemplates() {
+ return mPlainAttrTemplates;
+ }
+
+ public boolean isModMDerAttrTemplates() {
+ return modMDerAttrTemplates;
+ }
+
+ public void setModMDerAttrTemplates(final boolean modMDerAttrTemplates) {
+ this.modMDerAttrTemplates = modMDerAttrTemplates;
+ }
+
+ @XmlElementWrapper(name = "mDerAttrTemplates")
+ @XmlElement(name = "mDerAttrTemplate")
+ @JsonProperty("mDerAttrTemplates")
+ public List<String> getMDerAttrTemplates() {
+ return mDerAttrTemplates;
+ }
+
+ public boolean isModMVirAttrTemplates() {
+ return modMVirAttrTemplates;
+ }
+
+ public void setModMVirAttrTemplates(final boolean modMVirAttrTemplates) {
+ this.modMVirAttrTemplates = modMVirAttrTemplates;
+ }
+
+ @XmlElementWrapper(name = "mVirAttrTemplates")
+ @XmlElement(name = "mVirAttrTemplate")
+ @JsonProperty("mVirAttrTemplates")
+ public List<String> getMVirAttrTemplates() {
+ return mVirAttrTemplates;
+ }
+
+ public ReferenceMod getPasswordPolicy() {
+ return passwordPolicy;
+ }
+
+ public void setPasswordPolicy(final ReferenceMod passwordPolicy) {
+ this.passwordPolicy = passwordPolicy;
+ }
+
+ public Boolean getInheritPasswordPolicy() {
+ return inheritPasswordPolicy;
+ }
+
+ public void setInheritPasswordPolicy(final Boolean inheritPasswordPolicy) {
+ this.inheritPasswordPolicy = inheritPasswordPolicy;
+ }
+
+ public ReferenceMod getAccountPolicy() {
+ return accountPolicy;
+ }
+
+ public void setAccountPolicy(final ReferenceMod accountPolicy) {
+ this.accountPolicy = accountPolicy;
+ }
+
+ public Boolean getInheritAccountPolicy() {
+ return inheritAccountPolicy;
+ }
+
+ public void setInheritAccountPolicy(final Boolean inheritAccountPolicy) {
+ this.inheritAccountPolicy = inheritAccountPolicy;
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty() && name == null && userOwner == null && roleOwner == null
+ && inheritTemplates == null && inheritOwner == null
+ && inheritAccountPolicy == null && inheritPasswordPolicy == null
+ && inheritPlainAttrs == null && inheritDerAttrs == null && inheritVirAttrs == null
+ && accountPolicy == null && passwordPolicy == null && entitlements.isEmpty()
+ && rPlainAttrTemplates.isEmpty() && rDerAttrTemplates.isEmpty() && rVirAttrTemplates.isEmpty()
+ && mPlainAttrTemplates.isEmpty() && mDerAttrTemplates.isEmpty() && mVirAttrTemplates.isEmpty();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
new file mode 100644
index 0000000..57ea366
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/StatusMod.java
@@ -0,0 +1,108 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "statusMod")
+@XmlType
+public class StatusMod extends AbstractBaseBean {
+
+ private static final long serialVersionUID = 3230910033784302656L;
+
+ @XmlEnum
+ @XmlType(name = "statusModType")
+ public enum ModType {
+
+ ACTIVATE,
+ SUSPEND,
+ REACTIVATE;
+
+ }
+
+ /**
+ * Key of user to for which status update is requested.
+ */
+ private long key;
+
+ private ModType type;
+
+ /**
+ * Update token (if required).
+ */
+ private String token;
+
+ /**
+ * Whether update should be performed on internal storage.
+ */
+ private boolean onSyncope = true;
+
+ /**
+ * External resources for which update is needed to be propagated.
+ */
+ private final List<String> resourceNames = new ArrayList<>();
+
+ public long getKey() {
+ return key;
+ }
+
+ public void setKey(long key) {
+ this.key = key;
+ }
+
+ public ModType getType() {
+ return type;
+ }
+
+ public void setType(final ModType type) {
+ this.type = type;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setToken(final String token) {
+ this.token = token;
+ }
+
+ public boolean isOnSyncope() {
+ return onSyncope;
+ }
+
+ public void setOnSyncope(final boolean onSyncope) {
+ this.onSyncope = onSyncope;
+ }
+
+ @XmlElementWrapper(name = "resources")
+ @XmlElement(name = "resource")
+ @JsonProperty("resources")
+ public List<String> getResourceNames() {
+ return resourceNames;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
new file mode 100644
index 0000000..0f421be
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/UserMod.java
@@ -0,0 +1,123 @@
+/*
+ * 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.common.lib.mod;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.HashSet;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "userMod")
+@XmlType
+public class UserMod extends AbstractSubjectMod {
+
+ private static final long serialVersionUID = 3081848906558106204L;
+
+ private String password;
+
+ private String username;
+
+ private final Set<MembershipMod> membershipsToAdd;
+
+ private final Set<Long> membershipsToRemove;
+
+ private StatusMod pwdPropRequest;
+
+ private Long securityQuestion;
+
+ private String securityAnswer;
+
+ public UserMod() {
+ super();
+
+ membershipsToAdd = new HashSet<>();
+ membershipsToRemove = new HashSet<>();
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(final String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(final String password) {
+ this.password = password;
+ }
+
+ @XmlElementWrapper(name = "membershipsToAdd")
+ @XmlElement(name = "membership")
+ @JsonProperty("membershipsToAdd")
+ public Set<MembershipMod> getMembershipsToAdd() {
+ return membershipsToAdd;
+ }
+
+ @XmlElementWrapper(name = "membershipsToRemove")
+ @XmlElement(name = "membership")
+ @JsonProperty("membershipsToRemove")
+ public Set<Long> getMembershipsToRemove() {
+ return membershipsToRemove;
+ }
+
+ public StatusMod getPwdPropRequest() {
+ return pwdPropRequest;
+ }
+
+ public void setPwdPropRequest(final StatusMod pwdPropRequest) {
+ this.pwdPropRequest = pwdPropRequest;
+ }
+
+ public Long getSecurityQuestion() {
+ return securityQuestion;
+ }
+
+ public void setSecurityQuestion(final Long securityQuestion) {
+ this.securityQuestion = securityQuestion;
+ }
+
+ public String getSecurityAnswer() {
+ return securityAnswer;
+ }
+
+ public void setSecurityAnswer(final String securityAnswer) {
+ this.securityAnswer = securityAnswer;
+ }
+
+ @JsonIgnore
+ @Override
+ public boolean isEmpty() {
+ return super.isEmpty()
+ && password == null
+ && username == null
+ && membershipsToAdd.isEmpty()
+ && membershipsToRemove.isEmpty()
+ && pwdPropRequest == null
+ && securityQuestion == null
+ && securityAnswer == null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/mod/package-info.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/mod/package-info.java b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/package-info.java
new file mode 100644
index 0000000..866b275
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/mod/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+@XmlSchema(namespace = SyncopeConstants.NAMESPACE)
+package org.apache.syncope.common.lib.mod;
+
+import javax.xml.bind.annotation.XmlSchema;
+import org.apache.syncope.common.lib.SyncopeConstants;
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/package-info.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/package-info.java b/common/lib/src/main/java/org/apache/syncope/common/lib/package-info.java
new file mode 100644
index 0000000..8eac5d5
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+@XmlSchema(namespace = SyncopeConstants.NAMESPACE)
+package org.apache.syncope.common.lib;
+
+import javax.xml.bind.annotation.XmlSchema;
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
new file mode 100644
index 0000000..0082591
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/AbstractReportletConf.java
@@ -0,0 +1,51 @@
+/*
+ * 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.common.lib.report;
+
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlType
+@XmlSeeAlso({ StaticReportletConf.class, UserReportletConf.class, RoleReportletConf.class })
+public abstract class AbstractReportletConf extends AbstractBaseBean implements ReportletConf {
+
+ private static final long serialVersionUID = -6130008602014516608L;
+
+ private String name;
+
+ public AbstractReportletConf() {
+ this(StringUtils.EMPTY);
+ setName(getClass().getName());
+ }
+
+ public AbstractReportletConf(final String name) {
+ this.name = name;
+ }
+
+ @Override
+ public final String getName() {
+ return name;
+ }
+
+ public final void setName(final String name) {
+ this.name = name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/report/ReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/ReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/ReportletConf.java
new file mode 100644
index 0000000..57bcf52
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/ReportletConf.java
@@ -0,0 +1,32 @@
+/*
+ * 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.common.lib.report;
+
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
+public interface ReportletConf {
+
+ /**
+ * Give name of related reportlet instance.
+ *
+ * @return name of this reportlet instance
+ */
+ String getName();
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
new file mode 100644
index 0000000..9f73d3d
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/RoleReportletConf.java
@@ -0,0 +1,109 @@
+/*
+ * 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.common.lib.report;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.annotation.FormAttributeField;
+import org.apache.syncope.common.lib.types.IntMappingType;
+
+@XmlRootElement(name = "roleReportletConf")
+@XmlType
+public class RoleReportletConf extends AbstractReportletConf {
+
+ private static final long serialVersionUID = -8488503068032439699L;
+
+ @XmlEnum
+ @XmlType(name = "roleReportletConfFeature")
+ public enum Feature {
+
+ key,
+ name,
+ roleOwner,
+ userOwner,
+ entitlements,
+ users,
+ resources
+
+ }
+
+ @FormAttributeField(userSearch = true)
+ private String matchingCond;
+
+ @FormAttributeField(schema = IntMappingType.RolePlainSchema)
+ private final List<String> plainAttrs = new ArrayList<>();
+
+ @FormAttributeField(schema = IntMappingType.RoleDerivedSchema)
+ private final List<String> derAttrs = new ArrayList<>();
+
+ @FormAttributeField(schema = IntMappingType.RoleVirtualSchema)
+ private final List<String> virAttrs = new ArrayList<>();
+
+ private final List<Feature> features = new ArrayList<>();
+
+ public RoleReportletConf() {
+ super();
+ }
+
+ public RoleReportletConf(final String name) {
+ super(name);
+ }
+
+ @XmlElementWrapper(name = "plainAttributes")
+ @XmlElement(name = "plainAttribute")
+ @JsonProperty("plainAttributes")
+ public List<String> getPlainAttrs() {
+ return plainAttrs;
+ }
+
+ @XmlElementWrapper(name = "derivedAttributes")
+ @XmlElement(name = "attribute")
+ @JsonProperty("derivedAttributes")
+ public List<String> getDerAttrs() {
+ return derAttrs;
+ }
+
+ @XmlElementWrapper(name = "virtualAttributes")
+ @XmlElement(name = "attribute")
+ @JsonProperty("virtualAttributes")
+ public List<String> getVirAttrs() {
+ return virAttrs;
+ }
+
+ @XmlElementWrapper(name = "features")
+ @XmlElement(name = "feature")
+ @JsonProperty("features")
+ public List<Feature> getFeatures() {
+ return features;
+ }
+
+ public String getMatchingCond() {
+ return matchingCond;
+ }
+
+ public void setMatchingCond(final String matchingCond) {
+ this.matchingCond = matchingCond;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/common/lib/src/main/java/org/apache/syncope/common/lib/report/StaticReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/StaticReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/StaticReportletConf.java
new file mode 100644
index 0000000..9160089
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/StaticReportletConf.java
@@ -0,0 +1,107 @@
+/*
+ * 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.common.lib.report;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.types.TraceLevel;
+
+@XmlRootElement(name = "staticReportletConf")
+@XmlType
+public class StaticReportletConf extends AbstractReportletConf {
+
+ private static final long serialVersionUID = -4814950086361753689L;
+
+ private String stringField;
+
+ private Long longField;
+
+ private Double doubleField;
+
+ private Date dateField;
+
+ private TraceLevel traceLevel;
+
+ private final List<String> listField = new ArrayList<String>();
+
+ public StaticReportletConf() {
+ super();
+ }
+
+ public StaticReportletConf(final String name) {
+ super(name);
+ }
+
+ public Date getDateField() {
+ return dateField == null
+ ? null
+ : new Date(dateField.getTime());
+ }
+
+ public void setDateField(Date dateField) {
+ this.dateField = dateField == null
+ ? null
+ : new Date(dateField.getTime());
+ }
+
+ public Double getDoubleField() {
+ return doubleField;
+ }
+
+ public void setDoubleField(Double doubleField) {
+ this.doubleField = doubleField;
+ }
+
+ @XmlElementWrapper(name = "listField")
+ @XmlElement(name = "field")
+ @JsonProperty("listField")
+ public List<String> getListField() {
+ return listField;
+ }
+
+ public Long getLongField() {
+ return longField;
+ }
+
+ public void setLongField(Long longField) {
+ this.longField = longField;
+ }
+
+ public String getStringField() {
+ return stringField;
+ }
+
+ public void setStringField(String stringField) {
+ this.stringField = stringField;
+ }
+
+ public TraceLevel getTraceLevel() {
+ return traceLevel;
+ }
+
+ public void setTraceLevel(TraceLevel traceLevel) {
+ this.traceLevel = traceLevel;
+ }
+}