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 2018/02/13 16:01:57 UTC

[2/7] syncope git commit: [SYNCOPE-1274] Using Swagger annotations for TO hierarchies

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
----------------------------------------------------------------------
diff --git a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
index 80ec8d1..f6af472 100644
--- a/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
+++ b/client/enduser/src/main/java/org/apache/syncope/client/enduser/resources/SchemaResource.java
@@ -36,7 +36,7 @@ import org.apache.syncope.client.enduser.annotations.Resource;
 import org.apache.syncope.client.enduser.model.CustomAttribute;
 import org.apache.syncope.client.enduser.model.CustomAttributesInfo;
 import org.apache.syncope.client.enduser.model.SchemaResponse;
-import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.SchemaTO;
 import org.apache.syncope.common.lib.to.TypeExtensionTO;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.SchemaType;
@@ -91,8 +91,8 @@ public class SchemaResource extends BaseResource {
             Map<String, CustomAttributesInfo> customForm = SyncopeEnduserApplication.get().getCustomForm();
 
             SchemaService schemaService = SyncopeEnduserSession.get().getService(SchemaService.class);
-            final List<AbstractSchemaTO> plainSchemas = classes.isEmpty()
-                    ? Collections.<AbstractSchemaTO>emptyList()
+            final List<SchemaTO> plainSchemas = classes.isEmpty()
+                    ? Collections.<SchemaTO>emptyList()
                     : customForm == null || customForm.isEmpty() || customForm.get(SchemaType.PLAIN.name()) == null
                     ? schemaService.list(
                             new SchemaQuery.Builder().type(SchemaType.PLAIN).anyTypeClasses(classes).build())
@@ -100,9 +100,9 @@ public class SchemaResource extends BaseResource {
                     ? customizeSchemas(schemaService.list(new SchemaQuery.Builder().type(SchemaType.PLAIN).
                             anyTypeClasses(classes).build()), group, customForm.get(SchemaType.PLAIN.name()).
                             getAttributes())
-                    : Collections.<AbstractSchemaTO>emptyList();
-            final List<AbstractSchemaTO> derSchemas = classes.isEmpty()
-                    ? Collections.<AbstractSchemaTO>emptyList()
+                    : Collections.<SchemaTO>emptyList();
+            final List<SchemaTO> derSchemas = classes.isEmpty()
+                    ? Collections.<SchemaTO>emptyList()
                     : customForm == null || customForm.isEmpty() || customForm.get(SchemaType.DERIVED.name()) == null
                     ? schemaService.list(
                             new SchemaQuery.Builder().type(SchemaType.DERIVED).anyTypeClasses(classes).build())
@@ -110,9 +110,9 @@ public class SchemaResource extends BaseResource {
                     ? customizeSchemas(schemaService.list(new SchemaQuery.Builder().type(SchemaType.DERIVED).
                             anyTypeClasses(classes).build()), group, customForm.get(SchemaType.DERIVED.name()).
                             getAttributes())
-                    : Collections.<AbstractSchemaTO>emptyList();
-            final List<AbstractSchemaTO> virSchemas = classes.isEmpty()
-                    ? Collections.<AbstractSchemaTO>emptyList()
+                    : Collections.<SchemaTO>emptyList();
+            final List<SchemaTO> virSchemas = classes.isEmpty()
+                    ? Collections.<SchemaTO>emptyList()
                     : customForm == null || customForm.isEmpty() || customForm.get(SchemaType.VIRTUAL.name()) == null
                     ? schemaService.list(
                             new SchemaQuery.Builder().type(SchemaType.VIRTUAL).anyTypeClasses(classes).build())
@@ -120,7 +120,7 @@ public class SchemaResource extends BaseResource {
                     ? customizeSchemas(schemaService.list(new SchemaQuery.Builder().type(SchemaType.VIRTUAL).
                             anyTypeClasses(classes).build()), group, customForm.get(SchemaType.VIRTUAL.name()).
                             getAttributes())
-                    : Collections.<AbstractSchemaTO>emptyList();
+                    : Collections.<SchemaTO>emptyList();
 
             if (group != null) {
                 plainSchemas.forEach(schema -> {
@@ -158,8 +158,8 @@ public class SchemaResource extends BaseResource {
         return response;
     }
 
-    private List<AbstractSchemaTO> customizeSchemas(
-            final List<AbstractSchemaTO> schemaTOs,
+    private List<SchemaTO> customizeSchemas(
+            final List<SchemaTO> schemaTOs,
             final String groupParam,
             final Map<String, CustomAttribute> customForm) {
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
----------------------------------------------------------------------
diff --git a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
index c4105e8..8186c4f 100644
--- a/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
+++ b/client/lib/src/main/java/org/apache/syncope/client/lib/SyncopeClientFactoryBean.java
@@ -34,7 +34,7 @@ import org.apache.cxf.ext.logging.LoggingFeature;
 import org.apache.cxf.jaxrs.client.JAXRSClientFactoryBean;
 import org.apache.cxf.jaxrs.provider.JAXBElementProvider;
 import org.apache.cxf.staxutils.DocumentDepthProperties;
-import org.apache.syncope.common.lib.policy.AbstractPolicyTO;
+import org.apache.syncope.common.lib.policy.PolicyTO;
 import org.apache.syncope.common.rest.api.DateParamConverterProvider;
 import org.apache.syncope.common.rest.api.RESTHeaders;
 
@@ -102,7 +102,7 @@ public class SyncopeClientFactoryBean {
         defaultJAXBProvider.setMarshallerProperties(marshallerProperties);
 
         Map<String, String> collectionWrapperMap = new HashMap<>();
-        collectionWrapperMap.put(AbstractPolicyTO.class.getName(), "policies");
+        collectionWrapperMap.put(PolicyTO.class.getName(), "policies");
         defaultJAXBProvider.setCollectionWrapperMap(collectionWrapperMap);
 
         return defaultJAXBProvider;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/pom.xml
----------------------------------------------------------------------
diff --git a/common/lib/pom.xml b/common/lib/pom.xml
index f24f60a..82d5c72 100644
--- a/common/lib/pom.xml
+++ b/common/lib/pom.xml
@@ -49,6 +49,11 @@ under the License.
     </dependency>
 
     <dependency>
+      <groupId>io.swagger.core.v3</groupId>
+      <artifactId>swagger-annotations</artifactId>
+    </dependency>      
+
+    <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-annotations</artifactId>
     </dependency>

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/AbstractBaseBean.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/AbstractBaseBean.java b/common/lib/src/main/java/org/apache/syncope/common/lib/AbstractBaseBean.java
index 432b766..4562f70 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/AbstractBaseBean.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/AbstractBaseBean.java
@@ -25,7 +25,7 @@ import org.apache.commons.lang3.builder.EqualsBuilder;
 import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-import org.apache.syncope.common.lib.to.AbstractTaskTO;
+import org.apache.syncope.common.lib.to.TaskTO;
 import org.apache.syncope.common.lib.to.AnyObjectTO;
 import org.apache.syncope.common.lib.to.ReportTO;
 import org.apache.syncope.common.lib.to.GroupTO;
@@ -33,7 +33,7 @@ import org.apache.syncope.common.lib.to.UserTO;
 
 @XmlType
 // Reporting here only classes used via PagedResult
-@XmlSeeAlso({ AbstractTaskTO.class, ReportTO.class, GroupTO.class, UserTO.class, AnyObjectTO.class })
+@XmlSeeAlso({ TaskTO.class, ReportTO.class, GroupTO.class, UserTO.class, AnyObjectTO.class })
 public abstract class AbstractBaseBean implements Serializable {
 
     private static final long serialVersionUID = 3119542005279892164L;

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AbstractPatchItem.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AbstractPatchItem.java b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AbstractPatchItem.java
index ee86a88..6f72065 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AbstractPatchItem.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AbstractPatchItem.java
@@ -18,6 +18,8 @@
  */
 package org.apache.syncope.common.lib.patch;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
@@ -39,6 +41,8 @@ public abstract class AbstractPatchItem<T> extends AbstractPatch {
 
     private T value;
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public T getValue() {
         return value;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyObjectPatch.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyObjectPatch.java b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyObjectPatch.java
index 75298a9..9a37cae 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyObjectPatch.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyObjectPatch.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.common.lib.patch;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.HashSet;
 import java.util.Set;
 import javax.xml.bind.annotation.XmlElement;
@@ -38,6 +39,13 @@ public class AnyObjectPatch extends AnyPatch {
 
     private final Set<MembershipPatch> memberships = new HashSet<>();
 
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.patch.AnyObjectPatch")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public StringReplacePatchItem getName() {
         return name;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
index 0dadbf8..136c8ce 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/AnyPatch.java
@@ -20,20 +20,33 @@ package org.apache.syncope.common.lib.patch;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.HashSet;
 import java.util.Set;
 import javax.ws.rs.PathParam;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
 import org.apache.syncope.common.lib.to.AttrTO;
 
 @XmlType
+@XmlSeeAlso({ UserPatch.class, GroupPatch.class, AnyObjectPatch.class })
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@class")
+@JsonPropertyOrder(value = { "@class", "key" })
+@Schema(subTypes = { UserPatch.class, GroupPatch.class, AnyObjectPatch.class }, discriminatorProperty = "@class")
 public abstract class AnyPatch extends AbstractBaseBean implements AttributablePatch {
 
     private static final long serialVersionUID = -7445489774552440544L;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    private String discriminator;
+
     private String key;
 
     private StringReplacePatchItem realm;
@@ -46,6 +59,15 @@ public abstract class AnyPatch extends AbstractBaseBean implements AttributableP
 
     private final Set<StringPatchItem> resources = new HashSet<>();
 
+    @Schema(name = "@class", required = true, readOnly = false)
+    public abstract String getDiscriminator();
+
+    public void setDiscriminator(final String discriminator) {
+        // do nothing
+    }
+
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getKey() {
         return key;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
index 553711c..0ddddfb 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/GroupPatch.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.patch;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -52,6 +53,13 @@ public class GroupPatch extends AnyPatch {
 
     private final List<TypeExtensionTO> typeExtensions = new ArrayList<>();
 
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.patch.GroupPatch")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public StringReplacePatchItem getName() {
         return name;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/patch/UserPatch.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/UserPatch.java b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/UserPatch.java
index 5dc50f1..c9e7038 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/patch/UserPatch.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/patch/UserPatch.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.common.lib.patch;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.HashSet;
 import java.util.Set;
 import javax.xml.bind.annotation.XmlElement;
@@ -48,6 +49,13 @@ public class UserPatch extends AnyPatch {
 
     private final Set<StringPatchItem> roles = new HashSet<>();
 
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.patch.UserPatch")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public StringReplacePatchItem getUsername() {
         return username;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
deleted file mode 100644
index bc41628..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AbstractPolicyTO.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.policy;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import java.util.ArrayList;
-import java.util.List;
-import javax.ws.rs.PathParam;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlSeeAlso;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-import org.apache.syncope.common.lib.to.EntityTO;
-
-@XmlRootElement(name = "abstractPolicy")
-@XmlType
-@XmlSeeAlso({ AccountPolicyTO.class, PasswordPolicyTO.class, PullPolicyTO.class })
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public abstract class AbstractPolicyTO extends AbstractBaseBean implements EntityTO {
-
-    private static final long serialVersionUID = -2903888572649721035L;
-
-    private String key;
-
-    private String description;
-
-    private final List<String> usedByResources = new ArrayList<>();
-
-    private final List<String> usedByRealms = new ArrayList<>();
-
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @PathParam("key")
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(final String description) {
-        this.description = description;
-    }
-
-    @XmlElementWrapper(name = "usedByResources")
-    @XmlElement(name = "resource")
-    @JsonProperty("usedByResources")
-    public List<String> getUsedByResources() {
-        return usedByResources;
-    }
-
-    @XmlElementWrapper(name = "usedByRealms")
-    @XmlElement(name = "group")
-    @JsonProperty("usedByRealms")
-    public List<String> getUsedByRealms() {
-        return usedByRealms;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountPolicyTO.java
index 7811c00..bf05ea3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountPolicyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/AccountPolicyTO.java
@@ -19,16 +19,18 @@
 package org.apache.syncope.common.lib.policy;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 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.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "accountPolicy")
 @XmlType
-public class AccountPolicyTO extends AbstractPolicyTO implements ComposablePolicy {
+public class AccountPolicyTO extends PolicyTO implements ComposablePolicy {
 
     private static final long serialVersionUID = -1557150042828800134L;
 
@@ -40,6 +42,14 @@ public class AccountPolicyTO extends AbstractPolicyTO implements ComposablePolic
 
     private final List<String> passthroughResources = new ArrayList<>();
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.policy.AccountPolicyTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public boolean isPropagateSuspension() {
         return propagateSuspension;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordPolicyTO.java
index fd7d55c..9f71072 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordPolicyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PasswordPolicyTO.java
@@ -19,16 +19,18 @@
 package org.apache.syncope.common.lib.policy;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 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.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "passwordPolicy")
 @XmlType
-public class PasswordPolicyTO extends AbstractPolicyTO implements ComposablePolicy {
+public class PasswordPolicyTO extends PolicyTO implements ComposablePolicy {
 
     private static final long serialVersionUID = -5606086441294799690L;
 
@@ -38,6 +40,14 @@ public class PasswordPolicyTO extends AbstractPolicyTO implements ComposablePoli
 
     private final List<String> rules = new ArrayList<>();
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.policy.PasswordPolicyTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public boolean isAllowNullPassword() {
         return allowNullPassword;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyTO.java
new file mode 100644
index 0000000..f8ef978
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PolicyTO.java
@@ -0,0 +1,106 @@
+/*
+ * 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.policy;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.PathParam;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+import org.apache.syncope.common.lib.to.EntityTO;
+
+@XmlRootElement(name = "policy")
+@XmlType
+@XmlSeeAlso({ AccountPolicyTO.class, PasswordPolicyTO.class, PullPolicyTO.class })
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@class")
+@JsonPropertyOrder(value = { "@class", "key", "description" })
+@Schema(
+        subTypes = { AccountPolicyTO.class, PasswordPolicyTO.class, PullPolicyTO.class },
+        discriminatorProperty = "@class")
+public abstract class PolicyTO extends AbstractBaseBean implements EntityTO {
+
+    private static final long serialVersionUID = -2903888572649721035L;
+
+    @XmlTransient
+    @JsonProperty("@class")
+    private String discriminator;
+
+    private String key;
+
+    private String description;
+
+    private final List<String> usedByResources = new ArrayList<>();
+
+    private final List<String> usedByRealms = new ArrayList<>();
+
+    @Schema(name = "@class", required = true, readOnly = false)
+    public abstract String getDiscriminator();
+
+    public void setDiscriminator(final String discriminator) {
+        // do nothing
+    }
+
+    @Schema(readOnly = true)
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @PathParam("key")
+    @Override
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(final String description) {
+        this.description = description;
+    }
+
+    @Schema(readOnly = true)
+    @XmlElementWrapper(name = "usedByResources")
+    @XmlElement(name = "resource")
+    @JsonProperty("usedByResources")
+    public List<String> getUsedByResources() {
+        return usedByResources;
+    }
+
+    @Schema(readOnly = true)
+    @XmlElementWrapper(name = "usedByRealms")
+    @XmlElement(name = "group")
+    @JsonProperty("usedByRealms")
+    public List<String> getUsedByRealms() {
+        return usedByRealms;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
index 3ecdbf2..6ac847a 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/policy/PullPolicyTO.java
@@ -19,9 +19,11 @@
 package org.apache.syncope.common.lib.policy;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.HashMap;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
@@ -29,12 +31,20 @@ import org.apache.syncope.common.lib.types.ConflictResolutionAction;
 
 @XmlRootElement(name = "pullPolicy")
 @XmlType
-public class PullPolicyTO extends AbstractPolicyTO {
+public class PullPolicyTO extends PolicyTO {
 
     private static final long serialVersionUID = 993024634238024242L;
 
     private ConflictResolutionAction conflictResolutionAction;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.policy.PullPolicyTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
     private final Map<String, String> correlationRules = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAnnotatedBean.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAnnotatedBean.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAnnotatedBean.java
index 1459211..b9b71ba 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAnnotatedBean.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractAnnotatedBean.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.to;
 
 import org.apache.syncope.common.lib.AbstractBaseBean;
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.Date;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.commons.lang3.StringUtils;
@@ -64,6 +65,7 @@ public class AbstractAnnotatedBean extends AbstractBaseBean {
      */
     private Date lastChangeDate;
 
+    @Schema(readOnly = true)
     public String getCreator() {
         return creator;
     }
@@ -72,6 +74,7 @@ public class AbstractAnnotatedBean extends AbstractBaseBean {
         this.creator = creator;
     }
 
+    @Schema(readOnly = true)
     public Date getCreationDate() {
         if (creationDate != null) {
             return new Date(creationDate.getTime());
@@ -87,6 +90,7 @@ public class AbstractAnnotatedBean extends AbstractBaseBean {
         }
     }
 
+    @Schema(readOnly = true)
     public String getLastModifier() {
         return lastModifier;
     }
@@ -95,6 +99,7 @@ public class AbstractAnnotatedBean extends AbstractBaseBean {
         this.lastModifier = lastModifier;
     }
 
+    @Schema(readOnly = true)
     public Date getLastChangeDate() {
         if (lastChangeDate != null) {
             return new Date(lastChangeDate.getTime());

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
deleted file mode 100644
index 14637ee..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractProvisioningTaskTO.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.to;
-
-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.XmlSeeAlso;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.types.MatchingRule;
-import org.apache.syncope.common.lib.types.UnmatchingRule;
-
-@XmlRootElement(name = "abstractProvisioningTask")
-@XmlType
-@XmlSeeAlso({ PushTaskTO.class, PullTaskTO.class })
-public class AbstractProvisioningTaskTO extends SchedTaskTO {
-
-    private static final long serialVersionUID = -2143537546915809016L;
-
-    private String resource;
-
-    private boolean performCreate;
-
-    private boolean performUpdate;
-
-    private boolean performDelete;
-
-    private boolean syncStatus;
-
-    private UnmatchingRule unmatchingRule;
-
-    private MatchingRule matchingRule;
-
-    private final List<String> actions = new ArrayList<>();
-
-    public String getResource() {
-        return resource;
-    }
-
-    public void setResource(final String resource) {
-        this.resource = resource;
-    }
-
-    public boolean isPerformCreate() {
-        return performCreate;
-    }
-
-    public void setPerformCreate(final boolean performCreate) {
-        this.performCreate = performCreate;
-    }
-
-    public boolean isPerformUpdate() {
-        return performUpdate;
-    }
-
-    public void setPerformUpdate(final boolean performUpdate) {
-        this.performUpdate = performUpdate;
-    }
-
-    public boolean isPerformDelete() {
-        return performDelete;
-    }
-
-    public void setPerformDelete(final boolean performDelete) {
-        this.performDelete = performDelete;
-    }
-
-    public boolean isSyncStatus() {
-        return syncStatus;
-    }
-
-    public void setSyncStatus(final boolean syncStatus) {
-        this.syncStatus = syncStatus;
-    }
-
-    @XmlElementWrapper(name = "actions")
-    @XmlElement(name = "action")
-    @JsonProperty("actions")
-    public List<String> getActions() {
-        return actions;
-    }
-
-    public UnmatchingRule getUnmatchingRule() {
-        return unmatchingRule;
-    }
-
-    public void setUnmatchingRule(final UnmatchingRule unmatchigRule) {
-        this.unmatchingRule = unmatchigRule;
-    }
-
-    public MatchingRule getMatchingRule() {
-        return matchingRule;
-    }
-
-    public void setMatchingRule(final MatchingRule matchigRule) {
-        this.matchingRule = matchigRule;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
deleted file mode 100644
index 2917c98..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractSchemaTO.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.to;
-
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-import javax.ws.rs.PathParam;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlSeeAlso;
-import javax.xml.bind.annotation.XmlType;
-import org.apache.syncope.common.lib.AbstractBaseBean;
-
-@XmlRootElement(name = "abstractSchema")
-@XmlType
-@XmlSeeAlso({ PlainSchemaTO.class, DerSchemaTO.class, VirSchemaTO.class })
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public abstract class AbstractSchemaTO extends AbstractBaseBean implements EntityTO {
-
-    private static final long serialVersionUID = 4088388951694301759L;
-
-    private String key;
-
-    private String anyTypeClass;
-
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @PathParam("key")
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public String getAnyTypeClass() {
-        return anyTypeClass;
-    }
-
-    public void setAnyTypeClass(final String anyTypeClass) {
-        this.anyTypeClass = anyTypeClass;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractStartEndBean.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractStartEndBean.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractStartEndBean.java
index 88962c5..9a65fa3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractStartEndBean.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractStartEndBean.java
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.Date;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.AbstractBaseBean;
@@ -31,6 +32,7 @@ public class AbstractStartEndBean extends AbstractBaseBean {
 
     private Date end;
 
+    @Schema(readOnly = true)
     public Date getStart() {
         return start == null
                 ? null
@@ -43,6 +45,7 @@ public class AbstractStartEndBean extends AbstractBaseBean {
                 : new Date(start.getTime());
     }
 
+    @Schema(readOnly = true)
     public Date getEnd() {
         return end == null
                 ? null

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
deleted file mode 100644
index 65603f7..0000000
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AbstractTaskTO.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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.to;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.fasterxml.jackson.annotation.JsonTypeInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.ws.rs.PathParam;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlSeeAlso;
-import javax.xml.bind.annotation.XmlType;
-
-@XmlRootElement(name = "abstractTask")
-@XmlType
-@XmlSeeAlso({ PropagationTaskTO.class, SchedTaskTO.class, NotificationTaskTO.class })
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
-public abstract class AbstractTaskTO extends AbstractStartEndBean implements EntityTO {
-
-    private static final long serialVersionUID = 386450127003321197L;
-
-    private String key;
-
-    private String latestExecStatus;
-
-    private final List<ExecTO> executions = new ArrayList<>();
-
-    @Override
-    public String getKey() {
-        return key;
-    }
-
-    @PathParam("key")
-    @Override
-    public void setKey(final String key) {
-        this.key = key;
-    }
-
-    public String getLatestExecStatus() {
-        return latestExecStatus;
-    }
-
-    public void setLatestExecStatus(final String latestExecStatus) {
-        this.latestExecStatus = latestExecStatus;
-    }
-
-    @XmlElementWrapper(name = "executions")
-    @XmlElement(name = "execution")
-    @JsonProperty("executions")
-    public List<ExecTO> getExecutions() {
-        return executions;
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
index 61d8eb1..61c7173 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyObjectTO.java
@@ -20,12 +20,14 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "anyObject")
@@ -42,6 +44,14 @@ public class AnyObjectTO extends AnyTO implements GroupableRelatableTO {
 
     private final List<MembershipTO> dynMemberships = new ArrayList<>();
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.AnyObjectTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public String getName() {
         return name;
     }
@@ -80,6 +90,7 @@ public class AnyObjectTO extends AnyTO implements GroupableRelatableTO {
         return memberships;
     }
 
+    @Schema(readOnly = true)
     @XmlElementWrapper(name = "dynMemberships")
     @XmlElement(name = "dynMembership")
     @JsonProperty("dynMemberships")

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
index e411e1a..b29c6e4 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AnyTO.java
@@ -20,7 +20,9 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -29,15 +31,22 @@ import java.util.Set;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlType
 @XmlSeeAlso({ UserTO.class, GroupTO.class, AnyObjectTO.class })
-@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@class")
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@class")
+@JsonPropertyOrder(value = { "@class", "key", "type", "realm", "username", "name" })
+@Schema(subTypes = { UserTO.class, GroupTO.class, AnyObjectTO.class }, discriminatorProperty = "@class")
 public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, AttributableTO {
 
     private static final long serialVersionUID = -754311920679872084L;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    private String discriminator;
+
     private String key;
 
     private String type;
@@ -58,6 +67,14 @@ public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, A
 
     private final Set<String> resources = new HashSet<>();
 
+    @Schema(name = "@class", required = true, readOnly = false)
+    public abstract String getDiscriminator();
+
+    public void setDiscriminator(final String discriminator) {
+        // do nothing
+    }
+
+    @Schema(readOnly = true)
     @Override
     public String getKey() {
         return key;
@@ -68,6 +85,7 @@ public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, A
         this.key = key;
     }
 
+    @Schema(readOnly = true)
     public String getType() {
         return type;
     }
@@ -84,6 +102,7 @@ public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, A
         this.realm = realm;
     }
 
+    @Schema(readOnly = true)
     @XmlElementWrapper(name = "dynRealms")
     @XmlElement(name = "dynRealmF")
     @JsonProperty("dynRealms")
@@ -91,6 +110,7 @@ public abstract class AnyTO extends AbstractAnnotatedBean implements EntityTO, A
         return dynRealms;
     }
 
+    @Schema(readOnly = true)
     public String getStatus() {
         return status;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
index bd63527..82a47da 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/AttrTO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.to;
 
 import org.apache.syncope.common.lib.AbstractBaseBean;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -45,7 +46,7 @@ public class AttrTO extends AbstractBaseBean {
             return this;
         }
 
-        public Builder schemaInfo(final AbstractSchemaTO schemaInfo) {
+        public Builder schemaInfo(final SchemaTO schemaInfo) {
             instance.schemaInfo = schemaInfo;
             return this;
         }
@@ -73,7 +74,7 @@ public class AttrTO extends AbstractBaseBean {
     /**
      * (Optional) schema information for this attribute.
      */
-    private AbstractSchemaTO schemaInfo;
+    private SchemaTO schemaInfo;
 
     /**
      * Name of the schema that this attribute is referring to.
@@ -88,17 +89,20 @@ public class AttrTO extends AbstractBaseBean {
     /**
      * @return schema information for this attribute; may be {@code NULL}
      */
-    public AbstractSchemaTO getSchemaInfo() {
+    @Schema(readOnly = true)
+    public SchemaTO getSchemaInfo() {
         return schemaInfo;
     }
 
-    public void setSchemaInfo(final AbstractSchemaTO schemaInfo) {
+    public void setSchemaInfo(final SchemaTO schemaInfo) {
         this.schemaInfo = schemaInfo;
     }
 
     /**
      * @return the name of the schema that this attribute is referring to
      */
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getSchema() {
         return schema;
     }
@@ -115,9 +119,9 @@ public class AttrTO extends AbstractBaseBean {
     /**
      * @return attribute values as strings
      */
-    @XmlElementWrapper(name = "values")
-    @XmlElement(name = "value")
-    @JsonProperty("values")
+    @XmlElementWrapper(name = "values", required = true)
+    @XmlElement(name = "value", required = true)
+    @JsonProperty(value = "values", required = true)
     public List<String> getValues() {
         return values;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/DerSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/DerSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DerSchemaTO.java
index dc84864..d2242b5 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/DerSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/DerSchemaTO.java
@@ -18,17 +18,28 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
-@XmlRootElement(name = "derivedSchema")
+@XmlRootElement(name = "derSchema")
 @XmlType
-public class DerSchemaTO extends AbstractSchemaTO {
+public class DerSchemaTO extends SchemaTO {
 
     private static final long serialVersionUID = -6747399803792103108L;
 
     private String expression;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.DerSchemaTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public String getExpression() {
         return expression;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
index 3f0b163..e1de0d7 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/GroupTO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -28,6 +29,7 @@ import java.util.Optional;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
@@ -60,6 +62,14 @@ public class GroupTO extends AnyTO {
 
     private final List<TypeExtensionTO> typeExtensions = new ArrayList<>();
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.GroupTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     @Override
     public String getType() {
         return AnyTypeKind.GROUP.name();
@@ -102,6 +112,7 @@ public class GroupTO extends AnyTO {
         this.udynMembershipCond = uDynMembershipCond;
     }
 
+    @Schema(readOnly = true)
     public int getStaticUserMembershipCount() {
         return staticUserMembershipCount;
     }
@@ -110,6 +121,7 @@ public class GroupTO extends AnyTO {
         this.staticUserMembershipCount = staticUserMembershipCount;
     }
 
+    @Schema(readOnly = true)
     public int getDynamicUserMembershipCount() {
         return dynamicUserMembershipCount;
     }
@@ -118,6 +130,7 @@ public class GroupTO extends AnyTO {
         this.dynamicUserMembershipCount = dynamicUserMembershipCount;
     }
 
+    @Schema(readOnly = true)
     public int getStaticAnyObjectMembershipCount() {
         return staticAnyObjectMembershipCount;
     }
@@ -126,6 +139,7 @@ public class GroupTO extends AnyTO {
         this.staticAnyObjectMembershipCount = staticAnyObjectMembershipCount;
     }
 
+    @Schema(readOnly = true)
     public int getDynamicAnyObjectMembershipCount() {
         return dynamicAnyObjectMembershipCount;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTaskTO.java
index 44155e4..0f6b4f1 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/NotificationTaskTO.java
@@ -19,18 +19,20 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 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.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.TraceLevel;
 
 @XmlRootElement(name = "notificationTask")
 @XmlType
-public class NotificationTaskTO extends AbstractTaskTO {
+public class NotificationTaskTO extends TaskTO {
 
     private static final long serialVersionUID = 371671242591093846L;
 
@@ -54,6 +56,15 @@ public class NotificationTaskTO extends AbstractTaskTO {
 
     private TraceLevel traceLevel;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.NotificationTaskTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
+    @Schema(readOnly = true)
     public String getNotification() {
         return notification;
     }
@@ -62,6 +73,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.notification = notification;
     }
 
+    @Schema(readOnly = true)
     public AnyTypeKind getAnyTypeKind() {
         return anyTypeKind;
     }
@@ -70,6 +82,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.anyTypeKind = anyTypeKind;
     }
 
+    @Schema(readOnly = true)
     public String getEntityKey() {
         return entityKey;
     }
@@ -78,6 +91,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.entityKey = entityKey;
     }
 
+    @Schema(readOnly = true)
     @XmlElementWrapper(name = "recipients")
     @XmlElement(name = "recipient")
     @JsonProperty("recipients")
@@ -85,6 +99,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         return recipients;
     }
 
+    @Schema(readOnly = true)
     public String getSender() {
         return sender;
     }
@@ -93,6 +108,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.sender = sender;
     }
 
+    @Schema(readOnly = true)
     public String getSubject() {
         return subject;
     }
@@ -101,6 +117,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.subject = subject;
     }
 
+    @Schema(readOnly = true)
     public String getTextBody() {
         return textBody;
     }
@@ -109,6 +126,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.textBody = textBody;
     }
 
+    @Schema(readOnly = true)
     public String getHtmlBody() {
         return htmlBody;
     }
@@ -117,6 +135,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.htmlBody = htmlBody;
     }
 
+    @Schema(readOnly = true)
     public boolean isExecuted() {
         return executed;
     }
@@ -125,6 +144,7 @@ public class NotificationTaskTO extends AbstractTaskTO {
         this.executed = executed;
     }
 
+    @Schema(readOnly = true)
     public TraceLevel getTraceLevel() {
         return traceLevel;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/PlainSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PlainSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PlainSchemaTO.java
index fc17702..2eba6f6 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PlainSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PlainSchemaTO.java
@@ -18,16 +18,19 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.syncope.common.lib.types.AttrSchemaType;
 import org.apache.syncope.common.lib.types.CipherAlgorithm;
 
-@XmlRootElement(name = "schema")
+@XmlRootElement(name = "plainSchema")
 @XmlType
-public class PlainSchemaTO extends AbstractSchemaTO {
+public class PlainSchemaTO extends SchemaTO {
 
     private static final long serialVersionUID = -8133983392476990308L;
 
@@ -55,6 +58,14 @@ public class PlainSchemaTO extends AbstractSchemaTO {
 
     private String mimeType;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.PlainSchemaTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public String getConversionPattern() {
         return conversionPattern;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
index 3ef94de..66f804e 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PropagationTaskTO.java
@@ -18,14 +18,18 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import org.apache.syncope.common.lib.types.AnyTypeKind;
 import org.apache.syncope.common.lib.types.ResourceOperation;
 
 @XmlRootElement(name = "propagationTask")
 @XmlType
-public class PropagationTaskTO extends AbstractTaskTO {
+public class PropagationTaskTO extends TaskTO {
 
     private static final long serialVersionUID = 386450127003321197L;
 
@@ -47,6 +51,16 @@ public class PropagationTaskTO extends AbstractTaskTO {
 
     private String entityKey;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.PropagationTaskTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getConnObjectKey() {
         return connObjectKey;
     }
@@ -63,6 +77,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.oldConnObjectKey = oldConnObjectKey;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getResource() {
         return resource;
     }
@@ -71,6 +87,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.resource = resource;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public ResourceOperation getOperation() {
         return operation;
     }
@@ -79,6 +97,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.operation = operation;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getAttributes() {
         return attributes;
     }
@@ -87,6 +107,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.attributes = attributes;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getObjectClassName() {
         return objectClassName;
     }
@@ -95,6 +117,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.objectClassName = objectClassName;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public AnyTypeKind getAnyTypeKind() {
         return anyTypeKind;
     }
@@ -103,6 +127,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.anyTypeKind = anyTypeKind;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getAnyType() {
         return anyType;
     }
@@ -111,6 +137,8 @@ public class PropagationTaskTO extends AbstractTaskTO {
         this.anyType = anyType;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getEntityKey() {
         return entityKey;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningTaskTO.java
new file mode 100644
index 0000000..c152190
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/ProvisioningTaskTO.java
@@ -0,0 +1,122 @@
+/*
+ * 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.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+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.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.types.MatchingRule;
+import org.apache.syncope.common.lib.types.UnmatchingRule;
+
+@XmlRootElement(name = "provisioningTask")
+@XmlType
+@XmlSeeAlso({ PushTaskTO.class, PullTaskTO.class })
+@Schema(subTypes = { PushTaskTO.class, PullTaskTO.class }, discriminatorProperty = "@class")
+public abstract class ProvisioningTaskTO extends SchedTaskTO {
+
+    private static final long serialVersionUID = -5722284116974636425L;
+
+    private String resource;
+
+    private boolean performCreate;
+
+    private boolean performUpdate;
+
+    private boolean performDelete;
+
+    private boolean syncStatus;
+
+    private UnmatchingRule unmatchingRule;
+
+    private MatchingRule matchingRule;
+
+    private final List<String> actions = new ArrayList<>();
+
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
+    public String getResource() {
+        return resource;
+    }
+
+    public void setResource(final String resource) {
+        this.resource = resource;
+    }
+
+    public boolean isPerformCreate() {
+        return performCreate;
+    }
+
+    public void setPerformCreate(final boolean performCreate) {
+        this.performCreate = performCreate;
+    }
+
+    public boolean isPerformUpdate() {
+        return performUpdate;
+    }
+
+    public void setPerformUpdate(final boolean performUpdate) {
+        this.performUpdate = performUpdate;
+    }
+
+    public boolean isPerformDelete() {
+        return performDelete;
+    }
+
+    public void setPerformDelete(final boolean performDelete) {
+        this.performDelete = performDelete;
+    }
+
+    public boolean isSyncStatus() {
+        return syncStatus;
+    }
+
+    public void setSyncStatus(final boolean syncStatus) {
+        this.syncStatus = syncStatus;
+    }
+
+    @XmlElementWrapper(name = "actions")
+    @XmlElement(name = "action")
+    @JsonProperty("actions")
+    public List<String> getActions() {
+        return actions;
+    }
+
+    public UnmatchingRule getUnmatchingRule() {
+        return unmatchingRule;
+    }
+
+    public void setUnmatchingRule(final UnmatchingRule unmatchigRule) {
+        this.unmatchingRule = unmatchigRule;
+    }
+
+    public MatchingRule getMatchingRule() {
+        return matchingRule;
+    }
+
+    public void setMatchingRule(final MatchingRule matchigRule) {
+        this.matchingRule = matchigRule;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
index 08edaf2..16e578d 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PullTaskTO.java
@@ -19,11 +19,14 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.HashMap;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
@@ -32,16 +35,28 @@ import org.apache.syncope.common.lib.types.PullMode;
 @XmlRootElement(name = "pullTask")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
-public class PullTaskTO extends AbstractProvisioningTaskTO implements TemplatableTO {
+public class PullTaskTO extends ProvisioningTaskTO implements TemplatableTO {
 
     private static final long serialVersionUID = -2143537546915809017L;
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     private PullMode pullMode;
 
     private String reconFilterBuilder;
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     private String destinationRealm;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.PullTaskTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
     private final Map<String, AnyTO> templates = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
index 7dfc623..2dc02c1 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/PushTaskTO.java
@@ -19,11 +19,14 @@
 package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.HashMap;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
@@ -31,15 +34,25 @@ import org.apache.syncope.common.lib.jaxb.XmlGenericMapAdapter;
 @XmlRootElement(name = "pushTask")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
-public class PushTaskTO extends AbstractProvisioningTaskTO {
+public class PushTaskTO extends ProvisioningTaskTO {
 
     private static final long serialVersionUID = -2143537546915809018L;
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     private String sourceRealm;
 
     @XmlJavaTypeAdapter(XmlGenericMapAdapter.class)
     private final Map<String, String> filters = new HashMap<>();
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.PushTaskTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public String getSourceRealm() {
         return sourceRealm;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
index e6c0697..d903ad3 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchedTaskTO.java
@@ -18,16 +18,20 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.Date;
-
+import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
 import javax.xml.bind.annotation.XmlType;
 
 @XmlRootElement(name = "schedTask")
 @XmlType
-@XmlSeeAlso(AbstractProvisioningTaskTO.class)
-public class SchedTaskTO extends AbstractTaskTO {
+@XmlSeeAlso({ ProvisioningTaskTO.class })
+@Schema(subTypes = { ProvisioningTaskTO.class }, discriminatorProperty = "@class")
+public class SchedTaskTO extends TaskTO {
 
     private static final long serialVersionUID = -5722284116974636425L;
 
@@ -47,6 +51,14 @@ public class SchedTaskTO extends AbstractTaskTO {
 
     private boolean active = true;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.SchedTaskTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public Date getStartAt() {
         return startAt == null ? null : new Date(startAt.getTime());
     }
@@ -71,6 +83,7 @@ public class SchedTaskTO extends AbstractTaskTO {
         this.jobDelegate = jobDelegate;
     }
 
+    @Schema(readOnly = true)
     public Date getLastExec() {
         return lastExec == null ? null : new Date(lastExec.getTime());
     }
@@ -79,6 +92,7 @@ public class SchedTaskTO extends AbstractTaskTO {
         this.lastExec = lastExec == null ? null : new Date(lastExec.getTime());
     }
 
+    @Schema(readOnly = true)
     public Date getNextExec() {
         return nextExec == null ? null : new Date(nextExec.getTime());
     }
@@ -99,6 +113,8 @@ public class SchedTaskTO extends AbstractTaskTO {
         return name;
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public void setName(final String name) {
         this.name = name;
     }
@@ -110,5 +126,4 @@ public class SchedTaskTO extends AbstractTaskTO {
     public void setActive(final boolean active) {
         this.active = active;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.java
new file mode 100644
index 0000000..99b5768
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/SchemaTO.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.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import javax.ws.rs.PathParam;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+import org.apache.syncope.common.lib.AbstractBaseBean;
+
+@XmlRootElement(name = "schema")
+@XmlType
+@XmlSeeAlso({ PlainSchemaTO.class, DerSchemaTO.class, VirSchemaTO.class })
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@class")
+@JsonPropertyOrder(value = { "@class", "key" })
+@Schema(subTypes = { PlainSchemaTO.class, DerSchemaTO.class, VirSchemaTO.class }, discriminatorProperty = "@class")
+public abstract class SchemaTO extends AbstractBaseBean implements EntityTO {
+
+    private static final long serialVersionUID = 4088388951694301759L;
+
+    @XmlTransient
+    @JsonProperty("@class")
+    private String discriminator;
+
+    private String key;
+
+    private String anyTypeClass;
+
+    @Schema(name = "@class", required = true, readOnly = false)
+    public abstract String getDiscriminator();
+
+    public void setDiscriminator(final String discriminator) {
+        // do nothing
+    }
+
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @PathParam("key")
+    @Override
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    public String getAnyTypeClass() {
+        return anyTypeClass;
+    }
+
+    public void setAnyTypeClass(final String anyTypeClass) {
+        this.anyTypeClass = anyTypeClass;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/TaskTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/TaskTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/TaskTO.java
new file mode 100644
index 0000000..4b175b3
--- /dev/null
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/TaskTO.java
@@ -0,0 +1,92 @@
+/*
+ * 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.to;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.PathParam;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSeeAlso;
+import javax.xml.bind.annotation.XmlTransient;
+import javax.xml.bind.annotation.XmlType;
+
+@XmlRootElement(name = "task")
+@XmlType
+@XmlSeeAlso({ PropagationTaskTO.class, ProvisioningTaskTO.class, NotificationTaskTO.class })
+@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "@class")
+@JsonPropertyOrder(value = { "@class", "key" })
+@Schema(
+        subTypes = { PropagationTaskTO.class, ProvisioningTaskTO.class, NotificationTaskTO.class },
+        discriminatorProperty = "@class")
+public abstract class TaskTO extends AbstractStartEndBean implements EntityTO {
+
+    private static final long serialVersionUID = 386450127003321197L;
+
+    @XmlTransient
+    @JsonProperty("@class")
+    private String discriminator;
+
+    private String key;
+
+    private String latestExecStatus;
+
+    private final List<ExecTO> executions = new ArrayList<>();
+
+    @Schema(name = "@class", required = true, readOnly = false)
+    public abstract String getDiscriminator();
+
+    public void setDiscriminator(final String discriminator) {
+        // do nothing
+    }
+
+    @Schema(readOnly = true)
+    @Override
+    public String getKey() {
+        return key;
+    }
+
+    @PathParam("key")
+    @Override
+    public void setKey(final String key) {
+        this.key = key;
+    }
+
+    @Schema(readOnly = true)
+    public String getLatestExecStatus() {
+        return latestExecStatus;
+    }
+
+    public void setLatestExecStatus(final String latestExecStatus) {
+        this.latestExecStatus = latestExecStatus;
+    }
+
+    @Schema(readOnly = true)
+    @XmlElementWrapper(name = "executions")
+    @XmlElement(name = "execution")
+    @JsonProperty("executions")
+    public List<ExecTO> getExecutions() {
+        return executions;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
index d518f0e..79d5c12 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/UserTO.java
@@ -20,6 +20,7 @@ package org.apache.syncope.common.lib.to;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
@@ -70,6 +71,13 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
 
     private final List<MembershipTO> dynMemberships = new ArrayList<>();
 
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.UserTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     @Override
     public String getType() {
         return AnyTypeKind.USER.name();
@@ -95,6 +103,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         return roles;
     }
 
+    @Schema(readOnly = true)
     @XmlElementWrapper(name = "dynRoles")
     @XmlElement(name = "role")
     @JsonProperty("dynRoles")
@@ -102,6 +111,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         return dynRoles;
     }
 
+    @Schema(readOnly = true)
     public String getToken() {
         return token;
     }
@@ -110,6 +120,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         this.token = token;
     }
 
+    @Schema(readOnly = true)
     public Date getTokenExpireTime() {
         if (tokenExpireTime != null) {
             return new Date(tokenExpireTime.getTime());
@@ -125,6 +136,8 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         }
     }
 
+    @JsonProperty(required = true)
+    @XmlElement(required = true)
     public String getUsername() {
         return username;
     }
@@ -133,6 +146,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         this.username = username;
     }
 
+    @Schema(readOnly = true)
     public Date getChangePwdDate() {
         if (changePwdDate != null) {
             return new Date(changePwdDate.getTime());
@@ -140,10 +154,12 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         return null;
     }
 
+    @Schema(readOnly = true)
     public Integer getFailedLogins() {
         return failedLogins;
     }
 
+    @Schema(readOnly = true)
     public Date getLastLoginDate() {
         if (lastLoginDate != null) {
             return new Date(lastLoginDate.getTime());
@@ -187,6 +203,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         this.securityAnswer = securityAnswer;
     }
 
+    @Schema(readOnly = true)
     public boolean isSuspended() {
         return suspended;
     }
@@ -195,6 +212,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         this.suspended = suspended;
     }
 
+    @Schema(readOnly = true)
     public boolean isMustChangePassword() {
         return mustChangePassword;
     }
@@ -233,6 +251,7 @@ public class UserTO extends AnyTO implements GroupableRelatableTO {
         return memberships;
     }
 
+    @Schema(readOnly = true)
     @XmlElementWrapper(name = "dynMemberships")
     @XmlElement(name = "dynMembership")
     @JsonProperty("dynMemberships")

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
index 1f10e6b..df7121b 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/VirSchemaTO.java
@@ -18,10 +18,13 @@
  */
 package org.apache.syncope.common.lib.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
 import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
 
-@XmlRootElement(name = "virtualSchema")
-public class VirSchemaTO extends AbstractSchemaTO {
+@XmlRootElement(name = "virSchema")
+public class VirSchemaTO extends SchemaTO {
 
     private static final long serialVersionUID = -8198557479659701343L;
 
@@ -33,6 +36,14 @@ public class VirSchemaTO extends AbstractSchemaTO {
 
     private String extAttrName;
 
+    @XmlTransient
+    @JsonProperty("@class")
+    @Schema(name = "@class", required = true, example = "org.apache.syncope.common.lib.to.VirSchemaTO")
+    @Override
+    public String getDiscriminator() {
+        return getClass().getName();
+    }
+
     public boolean isReadonly() {
         return readonly;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java
index 673666d..82f17ee 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/SchemaType.java
@@ -19,7 +19,7 @@
 package org.apache.syncope.common.lib.types;
 
 import javax.xml.bind.annotation.XmlEnum;
-import org.apache.syncope.common.lib.to.AbstractSchemaTO;
+import org.apache.syncope.common.lib.to.SchemaTO;
 import org.apache.syncope.common.lib.to.DerSchemaTO;
 import org.apache.syncope.common.lib.to.PlainSchemaTO;
 import org.apache.syncope.common.lib.to.VirSchemaTO;
@@ -40,17 +40,17 @@ public enum SchemaType {
      */
     VIRTUAL(VirSchemaTO.class);
 
-    private final Class<? extends AbstractSchemaTO> toClass;
+    private final Class<? extends SchemaTO> toClass;
 
-    SchemaType(final Class<? extends AbstractSchemaTO> toClass) {
+    SchemaType(final Class<? extends SchemaTO> toClass) {
         this.toClass = toClass;
     }
 
-    public Class<? extends AbstractSchemaTO> getToClass() {
+    public Class<? extends SchemaTO> getToClass() {
         return toClass;
     }
 
-    public static SchemaType fromToClass(final Class<? extends AbstractSchemaTO> toClass) {
+    public static SchemaType fromToClass(final Class<? extends SchemaTO> toClass) {
         SchemaType schemaType = null;
 
         if (PlainSchemaTO.class.equals(toClass)) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/0e93bec6/common/rest-api/pom.xml
----------------------------------------------------------------------
diff --git a/common/rest-api/pom.xml b/common/rest-api/pom.xml
index 5e1a137..fb073e8 100644
--- a/common/rest-api/pom.xml
+++ b/common/rest-api/pom.xml
@@ -47,11 +47,6 @@ under the License.
       <groupId>javax.ws.rs</groupId>
       <artifactId>javax.ws.rs-api</artifactId>
     </dependency>
-    
-    <dependency>
-      <groupId>io.swagger.core.v3</groupId>
-      <artifactId>swagger-annotations</artifactId>
-    </dependency>      
 
     <dependency>
       <groupId>org.apache.syncope.common</groupId>