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/01/12 17:31:59 UTC

[20/52] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Unit tests all in

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskCheck.java
new file mode 100644
index 0000000..ab76d09
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = PropagationTaskValidator.class)
+@Documented
+public @interface PropagationTaskCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.propagationtask}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskValidator.java
new file mode 100644
index 0000000..873516c
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/PropagationTaskValidator.java
@@ -0,0 +1,65 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.util.List;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PropagationTaskExecStatus;
+import org.apache.syncope.server.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.server.persistence.api.entity.task.TaskExec;
+
+public class PropagationTaskValidator extends AbstractValidator<PropagationTaskCheck, PropagationTask> {
+
+    @Override
+    public boolean isValid(final PropagationTask task, final ConstraintValidatorContext context) {
+        boolean isValid;
+
+        if (task == null) {
+            isValid = true;
+        } else {
+            isValid = task.getPropagationMode() != null
+                    && task.getPropagationOperation() != null
+                    && !task.getAttributes().isEmpty()
+                    && task.getResource() != null;
+
+            if (isValid) {
+                List<? extends TaskExec> executions = task.getExecs();
+                for (TaskExec execution : executions) {
+                    try {
+                        PropagationTaskExecStatus.valueOf(execution.getStatus());
+                    } catch (IllegalArgumentException e) {
+                        LOG.error("Invalid execution status '" + execution.getStatus() + "'", e);
+                        isValid = false;
+                    }
+                }
+            }
+
+            if (!isValid) {
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidPropagationTask, "Invalid task")).
+                        addPropertyNode(task.getClass().getSimpleName()).addConstraintViolation();
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
new file mode 100644
index 0000000..f561cf8
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = ProvisioningTaskValidator.class)
+@Documented
+public @interface ProvisioningTaskCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.abstractsynctask}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
new file mode 100644
index 0000000..f76c072
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ProvisioningTaskValidator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.entity.task.ProvisioningTask;
+import org.apache.syncope.server.persistence.jpa.entity.task.JPAPushTask;
+import org.apache.syncope.server.persistence.jpa.entity.task.JPASyncTask;
+import org.apache.syncope.server.provisioning.api.sync.PushActions;
+import org.apache.syncope.server.provisioning.api.sync.SyncActions;
+
+public class ProvisioningTaskValidator extends AbstractValidator<ProvisioningTaskCheck, ProvisioningTask> {
+
+    private final SchedTaskValidator schedV;
+
+    public ProvisioningTaskValidator() {
+        super();
+
+        schedV = new SchedTaskValidator();
+    }
+
+    @Override
+    public boolean isValid(final ProvisioningTask object, final ConstraintValidatorContext context) {
+        boolean isValid = schedV.isValid(object, context);
+
+        if (isValid) {
+            isValid = object.getResource() != null;
+            if (!isValid) {
+                LOG.error("Resource is null");
+
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSyncTask, "Resource cannot be null")).
+                        addPropertyNode("resource").addConstraintViolation();
+            }
+
+            if (!object.getActionsClassNames().isEmpty()) {
+                for (String className : object.getActionsClassNames()) {
+                    Class<?> actionsClass = null;
+                    boolean isAssignable = false;
+                    try {
+                        actionsClass = Class.forName(className);
+                        isAssignable = object instanceof JPASyncTask
+                                ? SyncActions.class.isAssignableFrom(actionsClass)
+                                : object instanceof JPAPushTask
+                                        ? PushActions.class.isAssignableFrom(actionsClass)
+                                        : false;
+                    } catch (Exception e) {
+                        LOG.error("Invalid SyncActions specified", e);
+                        isValid = false;
+                    }
+
+                    if (actionsClass == null || !isAssignable) {
+                        isValid = false;
+
+                        context.disableDefaultConstraintViolation();
+                        context.buildConstraintViolationWithTemplate(
+                                getTemplate(EntityViolationType.InvalidSyncTask, "Invalid class name")).
+                                addPropertyNode("actionsClassName").addConstraintViolation();
+                    }
+                }
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportCheck.java
new file mode 100644
index 0000000..9d883db
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = ReportValidator.class)
+@Documented
+public @interface ReportCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.report}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportValidator.java
new file mode 100644
index 0000000..d05ca17
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/ReportValidator.java
@@ -0,0 +1,67 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.text.ParseException;
+import java.util.HashSet;
+import java.util.Set;
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.report.ReportletConf;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.entity.Report;
+import org.quartz.CronExpression;
+
+public class ReportValidator extends AbstractValidator<ReportCheck, Report> {
+
+    @Override
+    @SuppressWarnings("ResultOfObjectAllocationIgnored")
+    public boolean isValid(final Report object, final ConstraintValidatorContext context) {
+        boolean isValid = true;
+
+        if (object.getCronExpression() != null) {
+            try {
+                new CronExpression(object.getCronExpression());
+            } catch (ParseException e) {
+                LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+                isValid = false;
+
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidReport, "Invalid cron expression")).
+                        addPropertyNode("cronExpression").addConstraintViolation();
+            }
+        }
+
+        Set<String> reportletNames = new HashSet<>();
+        for (ReportletConf conf : object.getReportletConfs()) {
+            reportletNames.add(conf.getName());
+        }
+        if (reportletNames.size() != object.getReportletConfs().size()) {
+            LOG.error("Reportlet name must be unique");
+            isValid = false;
+
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidReport, "Reportlet name must be unique")).
+                    addPropertyNode("reportletConfs").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleCheck.java
new file mode 100644
index 0000000..1a294da
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = RoleValidator.class)
+@Documented
+public @interface RoleCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.syncoperole}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleValidator.java
new file mode 100644
index 0000000..94cbb3b
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/RoleValidator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+
+public class RoleValidator extends AbstractValidator<RoleCheck, Role> {
+
+    @Override
+    public boolean isValid(final Role object, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        boolean isValid = true;
+
+        if (object.getUserOwner() != null && object.getRoleOwner() != null) {
+            isValid = false;
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidRoleOwner,
+                            "A role must either be owned by an user or a role, not both")).
+                    addPropertyNode("owner").addConstraintViolation();
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskCheck.java
new file mode 100644
index 0000000..135b647
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = SchedTaskValidator.class)
+@Documented
+public @interface SchedTaskCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.schedtask}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskValidator.java
new file mode 100644
index 0000000..6088d49
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchedTaskValidator.java
@@ -0,0 +1,68 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.text.ParseException;
+
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.entity.task.SchedTask;
+import org.quartz.CronExpression;
+import org.quartz.Job;
+
+public class SchedTaskValidator extends AbstractValidator<SchedTaskCheck, SchedTask> {
+
+    @Override
+    public boolean isValid(final SchedTask object, final ConstraintValidatorContext context) {
+        boolean isValid;
+
+        Class<?> jobClass = null;
+        try {
+            jobClass = Class.forName(object.getJobClassName());
+            isValid = Job.class.isAssignableFrom(jobClass);
+        } catch (Exception e) {
+            LOG.error("Invalid Job class specified", e);
+            isValid = false;
+        }
+        if (jobClass == null || !isValid) {
+            isValid = false;
+
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidSchedTask, "Invalid job class name")).
+                    addPropertyNode("jobClassName").addConstraintViolation();
+        }
+
+        if (isValid && object.getCronExpression() != null) {
+            try {
+                new CronExpression(object.getCronExpression());
+            } catch (ParseException e) {
+                LOG.error("Invalid cron expression '" + object.getCronExpression() + "'", e);
+                isValid = false;
+
+                context.disableDefaultConstraintViolation();
+                context.buildConstraintViolationWithTemplate(
+                        getTemplate(EntityViolationType.InvalidSchedTask, "Invalid cron expression")).
+                        addPropertyNode("cronExpression").addConstraintViolation();
+            }
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameCheck.java
new file mode 100644
index 0000000..b26b2e1
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameCheck.java
@@ -0,0 +1,41 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = SchemaNameValidator.class)
+@Documented
+public @interface SchemaNameCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.schema}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameValidator.java
new file mode 100644
index 0000000..78da2aa
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/SchemaNameValidator.java
@@ -0,0 +1,133 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.validation.ConstraintValidatorContext;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.server.persistence.api.entity.conf.CPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.membership.MDerSchema;
+import org.apache.syncope.server.persistence.api.entity.membership.MPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.membership.MVirSchema;
+import org.apache.syncope.server.persistence.api.entity.role.RDerSchema;
+import org.apache.syncope.server.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.role.RVirSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UDerSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.server.persistence.api.entity.user.UVirSchema;
+import org.apache.syncope.server.persistence.jpa.entity.conf.JPAConf;
+import org.apache.syncope.server.persistence.jpa.entity.membership.JPAMembership;
+import org.apache.syncope.server.persistence.jpa.entity.role.JPARole;
+import org.apache.syncope.server.persistence.jpa.entity.user.JPAUser;
+
+public class SchemaNameValidator extends AbstractValidator<SchemaNameCheck, Object> {
+
+    private static final List<String> UNALLOWED_USCHEMA_NAMES = new ArrayList<>();
+
+    private static final List<String> UNALLOWED_MSCHEMA_NAMES = new ArrayList<>();
+
+    private static final List<String> UNALLOWED_RSCHEMA_NAMES = new ArrayList<>();
+
+    private static final List<String> UNALLOWED_CSCHEMA_NAMES = new ArrayList<>();
+
+    static {
+        initUnallowedSchemaNames(JPAUser.class, UNALLOWED_USCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAMembership.class, UNALLOWED_MSCHEMA_NAMES);
+        initUnallowedSchemaNames(JPARole.class, UNALLOWED_RSCHEMA_NAMES);
+        initUnallowedSchemaNames(JPAConf.class, UNALLOWED_CSCHEMA_NAMES);
+    }
+
+    private static void initUnallowedSchemaNames(final Class<?> entityClass, final List<String> names) {
+        List<Class<?>> classes = ClassUtils.getAllSuperclasses(entityClass);
+        classes.add(JPAUser.class);
+        for (Class<?> clazz : classes) {
+            for (Field field : clazz.getDeclaredFields()) {
+                if (!Collection.class.isAssignableFrom(field.getType())
+                        && !Map.class.isAssignableFrom(field.getType())) {
+
+                    names.add(field.getName());
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean isValid(final Object object, final ConstraintValidatorContext context) {
+        final String schemaName;
+        final List<String> unallowedNames;
+
+        if (object instanceof UPlainSchema) {
+            schemaName = ((UPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_USCHEMA_NAMES;
+        } else if (object instanceof UDerSchema) {
+            schemaName = ((UDerSchema) object).getKey();
+            unallowedNames = UNALLOWED_USCHEMA_NAMES;
+        } else if (object instanceof UVirSchema) {
+            schemaName = ((UVirSchema) object).getKey();
+            unallowedNames = UNALLOWED_USCHEMA_NAMES;
+        } else if (object instanceof MPlainSchema) {
+            schemaName = ((MPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
+        } else if (object instanceof MDerSchema) {
+            schemaName = ((MDerSchema) object).getKey();
+            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
+        } else if (object instanceof MVirSchema) {
+            schemaName = ((MVirSchema) object).getKey();
+            unallowedNames = UNALLOWED_MSCHEMA_NAMES;
+        } else if (object instanceof RPlainSchema) {
+            schemaName = ((RPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
+        } else if (object instanceof RDerSchema) {
+            schemaName = ((RDerSchema) object).getKey();
+            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
+        } else if (object instanceof RVirSchema) {
+            schemaName = ((RVirSchema) object).getKey();
+            unallowedNames = UNALLOWED_RSCHEMA_NAMES;
+        } else if (object instanceof CPlainSchema) {
+            schemaName = ((CPlainSchema) object).getKey();
+            unallowedNames = UNALLOWED_CSCHEMA_NAMES;
+        } else {
+            schemaName = null;
+            unallowedNames = Collections.emptyList();
+        }
+
+        boolean isValid = NAME_PATTERN.matcher(schemaName).matches();
+        if (!isValid) {
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidName, "Invalid Schema name")).
+                    addPropertyNode("name").addConstraintViolation();
+        } else if (unallowedNames.contains(schemaName)) {
+            context.disableDefaultConstraintViolation();
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidName, "Schema name not allowed: " + schemaName)).
+                    addPropertyNode("name").addConstraintViolation();
+
+            return false;
+        }
+
+        return isValid;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserCheck.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserCheck.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserCheck.java
new file mode 100644
index 0000000..23697fe
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserCheck.java
@@ -0,0 +1,42 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.validation.Constraint;
+import javax.validation.Payload;
+
+
+@Target( { ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Constraint(validatedBy = UserValidator.class)
+@Documented
+public @interface UserCheck {
+
+    String message() default "{org.apache.syncope.server.persistence.validation.syncopeuser}";
+
+    Class<?>[] groups() default {};
+
+    Class<? extends Payload>[] payload() default {};
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserValidator.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserValidator.java b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserValidator.java
new file mode 100644
index 0000000..93f8261
--- /dev/null
+++ b/syncope620/server/persistence-jpa/src/main/java/org/apache/syncope/server/persistence/jpa/validation/entity/UserValidator.java
@@ -0,0 +1,194 @@
+/*
+ * 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.server.persistence.jpa.validation.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Resource;
+import javax.validation.ConstraintValidatorContext;
+import org.apache.syncope.common.lib.types.AccountPolicySpec;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.PasswordPolicySpec;
+import org.apache.syncope.server.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.server.persistence.api.entity.AccountPolicy;
+import org.apache.syncope.server.persistence.api.entity.ExternalResource;
+import org.apache.syncope.server.persistence.api.entity.PasswordPolicy;
+import org.apache.syncope.server.persistence.api.entity.Policy;
+import org.apache.syncope.server.persistence.api.entity.role.Role;
+import org.apache.syncope.server.persistence.api.entity.user.User;
+import org.apache.syncope.server.misc.policy.AccountPolicyEnforcer;
+import org.apache.syncope.server.misc.policy.AccountPolicyException;
+import org.apache.syncope.server.misc.policy.PasswordPolicyEnforcer;
+import org.apache.syncope.server.misc.policy.PolicyEvaluator;
+import org.springframework.beans.factory.annotation.Autowired;
+
+public class UserValidator extends AbstractValidator<UserCheck, User> {
+
+    @Resource(name = "adminUser")
+    private String adminUser;
+
+    @Resource(name = "anonymousUser")
+    private String anonymousUser;
+
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
+    private PolicyEvaluator evaluator;
+
+    @Autowired
+    private PasswordPolicyEnforcer ppEnforcer;
+
+    @Autowired
+    private AccountPolicyEnforcer apEnforcer;
+
+    @Override
+    public boolean isValid(final User user, final ConstraintValidatorContext context) {
+        context.disableDefaultConstraintViolation();
+
+        // ------------------------------
+        // Verify password policies
+        // ------------------------------
+        LOG.debug("Password Policy enforcement");
+
+        try {
+            int maxPPSpecHistory = 0;
+            for (Policy policy : getPasswordPolicies(user)) {
+                // evaluate policy
+                final PasswordPolicySpec ppSpec = evaluator.evaluate(policy, user);
+                // enforce policy
+                ppEnforcer.enforce(ppSpec, policy.getType(), user);
+
+                if (ppSpec.getHistoryLength() > maxPPSpecHistory) {
+                    maxPPSpecHistory = ppSpec.getHistoryLength();
+                }
+            }
+
+            // update user's password history with encrypted password
+            if (maxPPSpecHistory > 0 && user.getPassword() != null) {
+                user.getPasswordHistory().add(user.getPassword());
+            }
+            // keep only the last maxPPSpecHistory items in user's password history
+            if (maxPPSpecHistory < user.getPasswordHistory().size()) {
+                for (int i = 0; i < user.getPasswordHistory().size() - maxPPSpecHistory; i++) {
+                    user.getPasswordHistory().remove(i);
+                }
+            }
+        } catch (Exception e) {
+            LOG.debug("Invalid password");
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidPassword, e.getMessage())).
+                    addPropertyNode("password").addConstraintViolation();
+
+            return false;
+        } finally {
+            // password has been validated, let's remove its clear version
+            user.removeClearPassword();
+        }
+        // ------------------------------
+
+        // ------------------------------
+        // Verify account policies
+        // ------------------------------
+        LOG.debug("Account Policy enforcement");
+
+        try {
+            if (adminUser.equals(user.getUsername()) || anonymousUser.equals(user.getUsername())) {
+                throw new AccountPolicyException("Not allowed: " + user.getUsername());
+            }
+
+            // invalid username
+            for (Policy policy : getAccountPolicies(user)) {
+                // evaluate policy
+                final AccountPolicySpec accountPolicy = evaluator.evaluate(policy, user);
+
+                // enforce policy
+                apEnforcer.enforce(accountPolicy, policy.getType(), user);
+            }
+        } catch (Exception e) {
+            LOG.debug("Invalid username");
+
+            context.buildConstraintViolationWithTemplate(
+                    getTemplate(EntityViolationType.InvalidUsername, e.getMessage())).
+                    addPropertyNode("username").addConstraintViolation();
+
+            return false;
+        }
+        // ------------------------------
+
+        return true;
+    }
+
+    private List<PasswordPolicy> getPasswordPolicies(final User user) {
+        final List<PasswordPolicy> policies = new ArrayList<>();
+
+        // Add global policy
+        PasswordPolicy policy = policyDAO.getGlobalPasswordPolicy();
+        if (policy != null) {
+            policies.add(policy);
+        }
+
+        // add resource policies
+        for (ExternalResource resource : user.getResources()) {
+            policy = resource.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add role policies
+        for (Role role : user.getRoles()) {
+            policy = role.getPasswordPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+
+    private List<AccountPolicy> getAccountPolicies(final User user) {
+        final List<AccountPolicy> policies = new ArrayList<>();
+
+        // add global policy
+        AccountPolicy policy = policyDAO.getGlobalAccountPolicy();
+        if (policy != null) {
+            policies.add(policy);
+        }
+
+        // add resource policies
+        for (ExternalResource resource : user.getResources()) {
+            policy = resource.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        // add role policies
+        for (Role role : user.getRoles()) {
+            policy = role.getAccountPolicy();
+            if (policy != null) {
+                policies.add(policy);
+            }
+        }
+
+        return policies;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
index 4ea467f..9a828d4 100644
--- a/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
+++ b/syncope620/server/persistence-jpa/src/main/resources/META-INF/orm.xml
@@ -26,7 +26,7 @@ under the License.
   <persistence-unit-metadata>
     <persistence-unit-defaults>
       <entity-listeners>
-        <entity-listener class="org.apache.syncope.persistence.jpa.validation.entity.EntityValidationListener">
+        <entity-listener class="org.apache.syncope.server.persistence.jpa.validation.entity.EntityValidationListener">
           <pre-persist method-name="validate"/>
           <pre-update method-name="validate"/>
         </entity-listener>
@@ -39,7 +39,7 @@ under the License.
   <table-generator name="SEQ_MAttrPlainValue" pk-column-value="SEQ_MAttrPlainValue" initial-value="100"/>
   <table-generator name="SEQ_CAttrPlainValue" pk-column-value="SEQ_CAttrPlainValue" initial-value="100"/>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUser">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.user.JPAUser">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_User" strategy="TABLE"/>
@@ -48,7 +48,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARole">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARole">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Role" strategy="TABLE"/>
@@ -57,7 +57,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMembership">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMembership">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Membership" strategy="TABLE"/>
@@ -66,7 +66,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUMapping">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.user.JPAUMapping">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_UMapping" strategy="TABLE"/>
@@ -74,7 +74,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARMapping">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARMapping">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_RMapping" strategy="TABLE"/>
@@ -82,7 +82,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUMappingItem">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.user.JPAUMappingItem">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_UMappingItem" strategy="TABLE"/>
@@ -90,7 +90,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARMappingItem">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARMappingItem">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_RMappingItem" strategy="TABLE"/>
@@ -99,7 +99,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPAConnInstance">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPAConnInstance">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_ConnInstance" strategy="TABLE"/>
@@ -108,7 +108,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUPlainAttr">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainAttr">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_UPlainAttr" strategy="TABLE"/>
@@ -116,7 +116,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARPlainAttr">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttr">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_RPlainAttr" strategy="TABLE"/>
@@ -124,7 +124,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMPlainAttr">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttr">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_MAttrPlain" strategy="TABLE"/>
@@ -132,7 +132,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.conf.JPACPlainAttr">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainAttr">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_CAttrPlain" strategy="TABLE"/>
@@ -141,14 +141,14 @@ under the License.
     </attributes>
   </entity>
     
-  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUPlainAttrValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainAttrValue">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_UPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -177,14 +177,14 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARPlainAttrValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttrValue">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_RPlainAttrValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.role.JPARPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.role.JPARPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -213,14 +213,14 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMPlainAttrValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrValue">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_MAttrPlainValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -249,14 +249,14 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.conf.JPACPlainAttrValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainAttrValue">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_CAttrPlainValue" strategy="TABLE"/>
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue">
     <table>
       <unique-constraint>
         <column-name>booleanValue</column-name>
@@ -286,7 +286,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.task.JPATask">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.task.JPATask">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Task" strategy="TABLE"/>
@@ -294,7 +294,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.task.JPATaskExec">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.task.JPATaskExec">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_TaskExec" strategy="TABLE"/>
@@ -303,7 +303,7 @@ under the License.
     </attributes>
   </entity>
     
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPAPolicy">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPAPolicy">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Policy" strategy="TABLE"/>
@@ -312,7 +312,7 @@ under the License.
     </attributes>
   </entity>
 
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPAReport">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPAReport">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Report" strategy="TABLE"/>
@@ -320,7 +320,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPAReportExec">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPAReportExec">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_ReportExec" strategy="TABLE"/>
@@ -328,7 +328,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPAReportletConfInstance">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPAReportletConfInstance">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_ReportletConfInstance" strategy="TABLE"/>
@@ -336,7 +336,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPANotification">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPANotification">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_Notification" strategy="TABLE"/>
@@ -344,7 +344,7 @@ under the License.
       </id>
     </attributes>
   </entity>
-  <entity class="org.apache.syncope.persistence.jpa.entity.JPASecurityQuestion">
+  <entity class="org.apache.syncope.server.persistence.jpa.entity.JPASecurityQuestion">
     <attributes>
       <id name="id">
         <generated-value generator="SEQ_SecurityQuestion" strategy="TABLE"/>

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/resources/content.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/content.xml b/syncope620/server/persistence-jpa/src/main/resources/content.xml
index 31919f4..e86262b 100644
--- a/syncope620/server/persistence-jpa/src/main/resources/content.xml
+++ b/syncope620/server/persistence-jpa/src/main/resources/content.xml
@@ -95,7 +95,7 @@ under the License.
   <!-- User pre-defined schemas -->
   <UPlainSchema name="email" type="String"
                 mandatoryCondition="false" multivalue="0" uniqueConstraint="0" readonly="0"
-                validatorClass="org.apache.syncope.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
+                validatorClass="org.apache.syncope.server.persistence.jpa.attrvalue.validation.EmailAddressValidator"/>
   
   <!-- Password reset notifications -->
   <Notification id="1" active="1" recipientAttrName="email" recipientAttrType="UserSchema" selfAsRecipient="1" 

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/main/resources/persistenceContext.xml
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/main/resources/persistenceContext.xml b/syncope620/server/persistence-jpa/src/main/resources/persistenceContext.xml
index df0b795..7b48b71 100644
--- a/syncope620/server/persistence-jpa/src/main/resources/persistenceContext.xml
+++ b/syncope620/server/persistence-jpa/src/main/resources/persistenceContext.xml
@@ -34,16 +34,6 @@ under the License.
   
   <import resource="persistenceContextEMFactory.xml"/>
 
-  <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
-    <property name="locations">
-      <list>
-        <value>classpath:persistence.properties</value>
-      </list>
-    </property>
-    <property name="ignoreResourceNotFound" value="true"/>
-    <property name="ignoreUnresolvablePlaceholders" value="true"/>
-  </bean>
-
   <bean id="nonJPAdbInitializer" class="org.springframework.jdbc.datasource.init.DataSourceInitializer">
     <property name="dataSource" ref="dataSource"/>
     <property name="enabled" value="true"/>
@@ -64,24 +54,24 @@ under the License.
   </bean>
   
   <context:annotation-config/>
-  <context:component-scan base-package="org.apache.syncope.persistence.jpa"/>
+  <context:component-scan base-package="org.apache.syncope.server.persistence.jpa"/>
 
   <bean id="database.schema" class="java.lang.String">
     <constructor-arg value="${database.schema}"/>
   </bean>
-  <bean id="persistenceProperties" class="org.apache.syncope.server.spring.ResourceWithFallbackLoader">
+  <bean id="persistenceProperties" class="org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${conf.directory}/persistence.properties"/>
     <property name="fallback" value="classpath:persistence.properties"/>
   </bean>
-  <bean id="contentXML" class="org.apache.syncope.server.spring.ResourceWithFallbackLoader">
+  <bean id="contentXML" class="org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${conf.directory}/content.xml"/>
     <property name="fallback" value="classpath:content.xml"/>
   </bean>
-  <bean id="viewsXML" class="org.apache.syncope.server.spring.ResourceWithFallbackLoader">
+  <bean id="viewsXML" class="org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${conf.directory}/views.xml"/>
     <property name="fallback" value="classpath:views.xml"/>
   </bean>
-  <bean id="indexesXML" class="org.apache.syncope.server.spring.ResourceWithFallbackLoader">
+  <bean id="indexesXML" class="org.apache.syncope.server.misc.spring.ResourceWithFallbackLoader">
     <property name="primary" value="file:${conf.directory}/indexes.xml"/>
     <property name="fallback" value="classpath:indexes.xml"/>
   </bean>

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/AbstractTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/AbstractTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/AbstractTest.java
deleted file mode 100644
index afb405a..0000000
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/AbstractTest.java
+++ /dev/null
@@ -1,38 +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.persistence.jpa;
-
-import org.apache.syncope.persistence.api.entity.AttributableUtilFactory;
-import org.apache.syncope.persistence.api.entity.EntityFactory;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-@RunWith(SpringJUnit4ClassRunner.class)
-@ContextConfiguration(locations = { "classpath:persistenceTestEnv.xml" })
-public abstract class AbstractTest {
-
-    @Autowired
-    protected EntityFactory entityFactory;
-
-    @Autowired
-    protected AttributableUtilFactory attrUtilFactory;
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/DummyConnectorRegistry.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/DummyConnectorRegistry.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/DummyConnectorRegistry.java
deleted file mode 100644
index 94c639c..0000000
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/DummyConnectorRegistry.java
+++ /dev/null
@@ -1,37 +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.persistence.jpa;
-
-import org.apache.syncope.persistence.api.dao.NotFoundException;
-import org.apache.syncope.persistence.api.entity.ExternalResource;
-import org.apache.syncope.provisioning.api.ConnectorRegistry;
-import org.springframework.stereotype.Component;
-
-@Component
-public class DummyConnectorRegistry implements ConnectorRegistry {
-
-    @Override
-    public void registerConnector(final ExternalResource resource)
-            throws NotFoundException {
-    }
-
-    @Override
-    public void unregisterConnector(final String id) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/TestInitializer.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/TestInitializer.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/TestInitializer.java
deleted file mode 100644
index ec29345..0000000
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/TestInitializer.java
+++ /dev/null
@@ -1,37 +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.persistence.jpa;
-
-import org.apache.syncope.persistence.api.content.ContentLoader;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class TestInitializer implements InitializingBean {
-
-    @Autowired
-    private ContentLoader contentLoader;
-
-    @Override
-    public void afterPropertiesSet() throws Exception {
-        contentLoader.load();
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/syncope/blob/235f60fa/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/entity/AttrTest.java
----------------------------------------------------------------------
diff --git a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/entity/AttrTest.java b/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/entity/AttrTest.java
deleted file mode 100644
index 0b5ccf1..0000000
--- a/syncope620/server/persistence-jpa/src/test/java/org/apache/syncope/persistence/jpa/entity/AttrTest.java
+++ /dev/null
@@ -1,235 +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.persistence.jpa.entity;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-import java.util.Random;
-import javax.validation.ValidationException;
-import org.apache.syncope.common.lib.SyncopeConstants;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.common.lib.types.EntityViolationType;
-import org.apache.syncope.persistence.api.attrvalue.validation.InvalidEntityException;
-import org.apache.syncope.persistence.api.dao.PlainAttrDAO;
-import org.apache.syncope.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.persistence.api.dao.UserDAO;
-import org.apache.syncope.persistence.api.entity.user.UPlainAttr;
-import org.apache.syncope.persistence.api.entity.user.UPlainAttrUniqueValue;
-import org.apache.syncope.persistence.api.entity.user.UPlainSchema;
-import org.apache.syncope.persistence.api.entity.user.User;
-import org.apache.syncope.persistence.jpa.AbstractTest;
-import org.apache.syncope.server.security.Encryptor;
-import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.codec.Base64;
-import org.springframework.transaction.annotation.Transactional;
-
-@Transactional
-public class AttrTest extends AbstractTest {
-
-    @Autowired
-    private UserDAO userDAO;
-
-    @Autowired
-    private PlainAttrDAO plainAttrDAO;
-
-    @Autowired
-    private PlainSchemaDAO userSchemaDAO;
-
-    @Test
-    public void findById() {
-        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-        attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        assertNotNull("did not find expected attribute schema", attribute);
-    }
-
-    @Test
-    public void read() {
-        UPlainAttr attribute = plainAttrDAO.find(100L, UPlainAttr.class);
-        assertNotNull(attribute);
-        assertTrue(attribute.getValues().isEmpty());
-        assertNotNull(attribute.getUniqueValue());
-    }
-
-    @Test
-    public void save() throws ClassNotFoundException {
-        User user = userDAO.find(1L);
-
-        UPlainSchema emailSchema = userSchemaDAO.find("email", UPlainSchema.class);
-        assertNotNull(emailSchema);
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(emailSchema);
-        attribute.setOwner(user);
-
-        Exception thrown = null;
-        try {
-            attribute.addValue("john.doe@gmail.com", attrUtilFactory.getInstance(AttributableType.USER));
-            attribute.addValue("mario.rossi@gmail.com", attrUtilFactory.getInstance(AttributableType.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNull("no validation exception expected here ", thrown);
-
-        try {
-            attribute.addValue("http://www.apache.org", attrUtilFactory.getInstance(AttributableType.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNotNull("validation exception expected here ", thrown);
-    }
-
-    @Test
-    public void saveWithEnum() throws ClassNotFoundException {
-        User user = userDAO.find(1L);
-
-        UPlainSchema gender = userSchemaDAO.find("gender", UPlainSchema.class);
-        assertNotNull(gender);
-        assertNotNull(gender.getType());
-        assertNotNull(gender.getEnumerationValues());
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(gender);
-        attribute.setOwner(user);
-        user.addPlainAttr(attribute);
-
-        Exception thrown = null;
-
-        try {
-            attribute.addValue("A", attrUtilFactory.getInstance(AttributableType.USER));
-        } catch (ValidationException e) {
-            thrown = e;
-        }
-        assertNotNull("validation exception expected here ", thrown);
-
-        attribute.addValue("M", attrUtilFactory.getInstance(AttributableType.USER));
-
-        InvalidEntityException iee = null;
-        try {
-            userDAO.save(user);
-        } catch (InvalidEntityException e) {
-            iee = e;
-        }
-        assertNull(iee);
-    }
-
-    @Test
-    public void validateAndSave() {
-        User user = userDAO.find(1L);
-
-        final UPlainSchema emailSchema = userSchemaDAO.find("email", UPlainSchema.class);
-        assertNotNull(emailSchema);
-
-        final UPlainSchema fullnameSchema = userSchemaDAO.find("fullname", UPlainSchema.class);
-        assertNotNull(fullnameSchema);
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(emailSchema);
-
-        UPlainAttrUniqueValue uauv = entityFactory.newEntity(UPlainAttrUniqueValue.class);
-        uauv.setAttr(attribute);
-        uauv.setSchema(fullnameSchema);
-        uauv.setStringValue("a value");
-
-        attribute.setUniqueValue(uauv);
-
-        user.addPlainAttr(attribute);
-
-        InvalidEntityException iee = null;
-        try {
-            userDAO.save(user);
-            fail();
-        } catch (InvalidEntityException e) {
-            iee = e;
-        }
-        assertNotNull(iee);
-        // for attribute
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidValueList));
-        // for uauv
-        assertTrue(iee.hasViolation(EntityViolationType.InvalidUPlainSchema));
-    }
-
-    @Test
-    public void saveWithEncrypted() throws Exception {
-        User user = userDAO.find(1L);
-
-        final UPlainSchema obscureSchema = userSchemaDAO.find("obscure", UPlainSchema.class);
-        assertNotNull(obscureSchema);
-        assertNotNull(obscureSchema.getSecretKey());
-        assertNotNull(obscureSchema.getCipherAlgorithm());
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(obscureSchema);
-        attribute.addValue("testvalue", attrUtilFactory.getInstance(AttributableType.USER));
-        attribute.setOwner(user);
-        user.addPlainAttr(attribute);
-
-        userDAO.save(user);
-
-        UPlainAttr obscure = user.getPlainAttr("obscure");
-        assertNotNull(obscure);
-        assertEquals(1, obscure.getValues().size());
-        assertEquals(Encryptor.getInstance(obscureSchema.getSecretKey()).
-                encode("testvalue", obscureSchema.getCipherAlgorithm()), obscure.getValues().get(0).getStringValue());
-    }
-
-    @Test
-    public void saveWithBinary() throws UnsupportedEncodingException {
-        User user = userDAO.find(1L);
-
-        final UPlainSchema photoSchema = userSchemaDAO.find("photo", UPlainSchema.class);
-        assertNotNull(photoSchema);
-        assertNotNull(photoSchema.getMimeType());
-
-        final byte[] bytes = new byte[20];
-        new Random().nextBytes(bytes);
-        final String photoB64Value = new String(Base64.encode(bytes), SyncopeConstants.DEFAULT_ENCODING);
-
-        UPlainAttr attribute = entityFactory.newEntity(UPlainAttr.class);
-        attribute.setSchema(photoSchema);
-        attribute.addValue(photoB64Value, attrUtilFactory.getInstance(AttributableType.USER));
-        attribute.setOwner(user);
-        user.addPlainAttr(attribute);
-
-        userDAO.save(user);
-
-        UPlainAttr obscure = user.getPlainAttr("photo");
-        assertNotNull(obscure);
-        assertEquals(1, obscure.getValues().size());
-        assertTrue(Arrays.equals(bytes, obscure.getValues().get(0).getBinaryValue()));
-    }
-
-    @Test
-    public void delete() {
-        UPlainAttr attribute = plainAttrDAO.find(104L, UPlainAttr.class);
-        String attrSchemaName = attribute.getSchema().getKey();
-
-        plainAttrDAO.delete(attribute.getKey(), UPlainAttr.class);
-
-        UPlainSchema schema = userSchemaDAO.find(attrSchemaName, UPlainSchema.class);
-        assertNotNull("user attribute schema deleted when deleting values", schema);
-    }
-}