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/05/25 16:50:56 UTC
[20/29] syncope git commit: [SYNCOPE-666] Initial commit,
Travis CI builds disabled
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
new file mode 100644
index 0000000..d91b948
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnySearchDAO.java
@@ -0,0 +1,811 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.Entity;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+import javax.validation.ValidationException;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.Transformer;
+import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.core.misc.RealmUtils;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.GroupDAO;
+import org.apache.syncope.core.persistence.api.dao.RealmDAO;
+import org.apache.syncope.core.persistence.api.dao.AnySearchDAO;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.dao.search.AttributeCond;
+import org.apache.syncope.core.persistence.api.dao.search.MembershipCond;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.dao.search.ResourceCond;
+import org.apache.syncope.core.persistence.api.dao.search.RoleCond;
+import org.apache.syncope.core.persistence.api.dao.search.SearchCond;
+import org.apache.syncope.core.persistence.api.dao.search.AnyCond;
+import org.apache.syncope.core.persistence.api.dao.search.RelationshipCond;
+import org.apache.syncope.core.persistence.api.entity.Any;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.Realm;
+import org.apache.syncope.core.persistence.jpa.entity.JPAPlainSchema;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.util.ReflectionUtils;
+
+@Repository
+public class JPAAnySearchDAO extends AbstractDAO<Any<?, ?, ?>, Long> implements AnySearchDAO {
+
+ protected static final Logger LOG = LoggerFactory.getLogger(AnySearchDAO.class);
+
+ private static final String EMPTY_ATTR_QUERY = "SELECT any_id FROM user_search_attr WHERE 1=2";
+
+ @Autowired
+ private RealmDAO realmDAO;
+
+ @Autowired
+ private AnyObjectDAO anyObjectDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private GroupDAO groupDAO;
+
+ @Autowired
+ private PlainSchemaDAO schemaDAO;
+
+ @Autowired
+ private AnyUtilsFactory anyUtilsFactory;
+
+ private String getAdminRealmsFilter(final Set<String> adminRealms, final SearchSupport svs) {
+ Set<Long> realmKeys = new HashSet<>();
+ for (String realmPath : RealmUtils.normalize(adminRealms)) {
+ Realm realm = realmDAO.find(realmPath);
+ if (realm == null) {
+ LOG.warn("Ignoring invalid realm {}", realmPath);
+ } else {
+ CollectionUtils.collect(realmDAO.findDescendants(realm), new Transformer<Realm, Long>() {
+
+ @Override
+ public Long transform(final Realm descendant) {
+ return descendant.getKey();
+ }
+ }, realmKeys);
+ }
+ }
+
+ StringBuilder adminRealmFilter = new StringBuilder().
+ append("SELECT any_id FROM ").append(svs.field().name).
+ append(" WHERE realm_id IN (SELECT id AS realm_id FROM Realm");
+
+ boolean firstRealm = true;
+ for (Long realmKey : realmKeys) {
+ if (firstRealm) {
+ adminRealmFilter.append(" WHERE");
+ firstRealm = false;
+ } else {
+ adminRealmFilter.append(" OR");
+ }
+ adminRealmFilter.append(" id = ").append(realmKey);
+ }
+
+ adminRealmFilter.append(')');
+
+ return adminRealmFilter.toString();
+ }
+
+ @Override
+ public int count(final Set<String> adminRealms, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+ List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+
+ // 1. get the query string from the search condition
+ SearchSupport svs = new SearchSupport(typeKind);
+ StringBuilder queryString = getQuery(searchCondition, parameters, typeKind, svs);
+
+ // 2. take into account administrative realms
+ queryString.insert(0, "SELECT u.any_id FROM (");
+ queryString.append(") u WHERE any_id IN (");
+ queryString.append(getAdminRealmsFilter(adminRealms, svs)).append(')');
+
+ // 3. prepare the COUNT query
+ queryString.insert(0, "SELECT COUNT(any_id) FROM (");
+ queryString.append(") count_any_id");
+
+ Query countQuery = entityManager.createNativeQuery(queryString.toString());
+ fillWithParameters(countQuery, parameters);
+
+ return ((Number) countQuery.getSingleResult()).intValue();
+ }
+
+ @Override
+ public <T extends Any<?, ?, ?>> List<T> search(
+ final Set<String> adminRealms, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+
+ return search(adminRealms, searchCondition, Collections.<OrderByClause>emptyList(), typeKind);
+ }
+
+ @Override
+ public <T extends Any<?, ?, ?>> List<T> search(
+ final Set<String> adminRealms, final SearchCond searchCondition, final List<OrderByClause> orderBy,
+ final AnyTypeKind typeKind) {
+
+ return search(adminRealms, searchCondition, -1, -1, orderBy, typeKind);
+ }
+
+ @Override
+ public <T extends Any<?, ?, ?>> List<T> search(
+ final Set<String> adminRealms, final SearchCond searchCondition, final int page, final int itemsPerPage,
+ final List<OrderByClause> orderBy, final AnyTypeKind typeKind) {
+
+ List<T> result = Collections.<T>emptyList();
+
+ if (adminRealms != null && !adminRealms.isEmpty()) {
+ LOG.debug("Search condition:\n{}", searchCondition);
+
+ if (searchCondition != null && searchCondition.isValid()) {
+ try {
+ result = doSearch(adminRealms, searchCondition, page, itemsPerPage, orderBy, typeKind);
+ } catch (Exception e) {
+ LOG.error("While searching for {}", typeKind, e);
+ }
+ } else {
+ LOG.error("Invalid search condition:\n{}", searchCondition);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public <T extends Any<?, ?, ?>> boolean matches(
+ final T subject, final SearchCond searchCondition, final AnyTypeKind typeKind) {
+
+ List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+
+ // 1. get the query string from the search condition
+ SearchSupport svs = new SearchSupport(typeKind);
+ StringBuilder queryString = getQuery(searchCondition, parameters, typeKind, svs);
+
+ boolean matches;
+ if (queryString.length() == 0) {
+ // Could be empty: got into a group search with a single membership condition ...
+ matches = false;
+ } else {
+ // 2. take into account the passed user
+ queryString.insert(0, "SELECT u.any_id FROM (");
+ queryString.append(") u WHERE any_id=?").append(setParameter(parameters, subject.getKey()));
+
+ // 3. prepare the search query
+ Query query = entityManager.createNativeQuery(queryString.toString());
+
+ // 4. populate the search query with parameter values
+ fillWithParameters(query, parameters);
+
+ // 5. executes query
+ matches = !query.getResultList().isEmpty();
+ }
+
+ return matches;
+ }
+
+ private int setParameter(final List<Object> parameters, final Object parameter) {
+ int key;
+ synchronized (parameters) {
+ parameters.add(parameter);
+ key = parameters.size();
+ }
+
+ return key;
+ }
+
+ private void fillWithParameters(final Query query, final List<Object> parameters) {
+ for (int i = 0; i < parameters.size(); i++) {
+ if (parameters.get(i) instanceof Date) {
+ query.setParameter(i + 1, (Date) parameters.get(i), TemporalType.TIMESTAMP);
+ } else if (parameters.get(i) instanceof Boolean) {
+ query.setParameter(i + 1, ((Boolean) parameters.get(i))
+ ? 1
+ : 0);
+ } else {
+ query.setParameter(i + 1, parameters.get(i));
+ }
+ }
+ }
+
+ private StringBuilder buildSelect(final OrderBySupport orderBySupport) {
+ final StringBuilder select = new StringBuilder("SELECT u.any_id");
+
+ for (OrderBySupport.Item obs : orderBySupport.items) {
+ select.append(',').append(obs.select);
+ }
+ select.append(" FROM ");
+
+ return select;
+ }
+
+ private StringBuilder buildWhere(final OrderBySupport orderBySupport) {
+ final StringBuilder where = new StringBuilder(" u");
+ for (SearchSupport.SearchView searchView : orderBySupport.views) {
+ where.append(',').append(searchView.name).append(' ').append(searchView.alias);
+ }
+ where.append(" WHERE ");
+ for (SearchSupport.SearchView searchView : orderBySupport.views) {
+ where.append("u.any_id=").append(searchView.alias).append(".any_id AND ");
+ }
+
+ for (OrderBySupport.Item obs : orderBySupport.items) {
+ if (StringUtils.isNotBlank(obs.where)) {
+ where.append(obs.where).append(" AND ");
+ }
+ }
+ where.append("u.any_id IN (");
+
+ return where;
+ }
+
+ private StringBuilder buildOrderBy(final OrderBySupport orderBySupport) {
+ final StringBuilder orderBy = new StringBuilder();
+
+ for (OrderBySupport.Item obs : orderBySupport.items) {
+ orderBy.append(obs.orderBy).append(',');
+ }
+ if (!orderBySupport.items.isEmpty()) {
+ orderBy.insert(0, " ORDER BY ");
+ orderBy.deleteCharAt(orderBy.length() - 1);
+ }
+
+ return orderBy;
+ }
+
+ private OrderBySupport parseOrderBy(final AnyTypeKind type, final SearchSupport svs,
+ final List<OrderByClause> orderByClauses) {
+
+ final AnyUtils attrUtils = anyUtilsFactory.getInstance(type);
+
+ OrderBySupport orderBySupport = new OrderBySupport();
+
+ for (OrderByClause clause : orderByClauses) {
+ OrderBySupport.Item obs = new OrderBySupport.Item();
+
+ // Manage difference among external key attribute and internal JPA @Id
+ String fieldName = "key".equals(clause.getField()) ? "id" : clause.getField();
+
+ Field subjectField = ReflectionUtils.findField(attrUtils.anyClass(), fieldName);
+ if (subjectField == null) {
+ PlainSchema schema = schemaDAO.find(fieldName);
+ if (schema != null) {
+ if (schema.isUniqueConstraint()) {
+ orderBySupport.views.add(svs.uniqueAttr());
+
+ obs.select = new StringBuilder().
+ append(svs.uniqueAttr().alias).append('.').append(svs.fieldName(schema.getType())).
+ append(" AS ").append(fieldName).toString();
+ obs.where = new StringBuilder().
+ append(svs.uniqueAttr().alias).
+ append(".schema_name='").append(fieldName).append("'").toString();
+ obs.orderBy = fieldName + " " + clause.getDirection().name();
+ } else {
+ orderBySupport.views.add(svs.attr());
+
+ obs.select = new StringBuilder().
+ append(svs.attr().alias).append('.').append(svs.fieldName(schema.getType())).
+ append(" AS ").append(fieldName).toString();
+ obs.where = new StringBuilder().
+ append(svs.attr().alias).
+ append(".schema_name='").append(fieldName).append("'").toString();
+ obs.orderBy = fieldName + " " + clause.getDirection().name();
+ }
+ }
+ } else {
+ orderBySupport.views.add(svs.field());
+
+ obs.select = svs.field().alias + "." + fieldName;
+ obs.where = StringUtils.EMPTY;
+ obs.orderBy = svs.field().alias + "." + fieldName + " " + clause.getDirection().name();
+ }
+
+ if (obs.isEmpty()) {
+ LOG.warn("Cannot build any valid clause from {}", clause);
+ } else {
+ orderBySupport.items.add(obs);
+ }
+ }
+
+ return orderBySupport;
+ }
+
+ @SuppressWarnings("unchecked")
+ private <T extends Any<?, ?, ?>> List<T> doSearch(final Set<String> adminRealms,
+ final SearchCond nodeCond, final int page, final int itemsPerPage, final List<OrderByClause> orderBy,
+ final AnyTypeKind typeKind) {
+
+ List<Object> parameters = Collections.synchronizedList(new ArrayList<>());
+
+ // 1. get the query string from the search condition
+ SearchSupport svs = new SearchSupport(typeKind);
+ StringBuilder queryString = getQuery(nodeCond, parameters, typeKind, svs);
+
+ // 2. take into account administrative groups and ordering
+ OrderBySupport orderBySupport = parseOrderBy(typeKind, svs, orderBy);
+ if (queryString.charAt(0) == '(') {
+ queryString.insert(0, buildSelect(orderBySupport));
+ queryString.append(buildWhere(orderBySupport));
+ } else {
+ queryString.insert(0, buildSelect(orderBySupport).append('('));
+ queryString.append(')').append(buildWhere(orderBySupport));
+ }
+ queryString.
+ append(getAdminRealmsFilter(adminRealms, svs)).append(')').
+ append(buildOrderBy(orderBySupport));
+
+ // 3. prepare the search query
+ Query query = entityManager.createNativeQuery(queryString.toString());
+
+ // 4. page starts from 1, while setFirtResult() starts from 0
+ query.setFirstResult(itemsPerPage * (page <= 0 ? 0 : page - 1));
+
+ if (itemsPerPage >= 0) {
+ query.setMaxResults(itemsPerPage);
+ }
+
+ // 5. populate the search query with parameter values
+ fillWithParameters(query, parameters);
+
+ // 6. Prepare the result (avoiding duplicates)
+ List<T> result = new ArrayList<>();
+
+ for (Object subjectKey : query.getResultList()) {
+ long actualKey;
+ if (subjectKey instanceof Object[]) {
+ actualKey = ((Number) ((Object[]) subjectKey)[0]).longValue();
+ } else {
+ actualKey = ((Number) subjectKey).longValue();
+ }
+
+ T subject = typeKind == AnyTypeKind.USER
+ ? (T) userDAO.find(actualKey)
+ : typeKind == AnyTypeKind.GROUP
+ ? (T) groupDAO.find(actualKey)
+ : (T) anyObjectDAO.find(actualKey);
+ if (subject == null) {
+ LOG.error("Could not find {} with id {}, even though returned by the native query",
+ typeKind, actualKey);
+ } else {
+ if (!result.contains(subject)) {
+ result.add(subject);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private StringBuilder getQuery(final SearchCond nodeCond, final List<Object> parameters,
+ final AnyTypeKind type, final SearchSupport svs) {
+
+ StringBuilder query = new StringBuilder();
+
+ switch (nodeCond.getType()) {
+
+ case LEAF:
+ case NOT_LEAF:
+ if (nodeCond.getRelationshipCond() != null
+ && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
+
+ query.append(getQuery(nodeCond.getRelationshipCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+ }
+ if (nodeCond.getMembershipCond() != null
+ && (AnyTypeKind.USER == type || AnyTypeKind.ANY_OBJECT == type)) {
+
+ query.append(getQuery(nodeCond.getMembershipCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+ }
+ if (nodeCond.getRoleCond() != null && AnyTypeKind.USER == type) {
+ query.append(getQuery(nodeCond.getRoleCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, svs));
+ }
+ if (nodeCond.getResourceCond() != null) {
+ query.append(getQuery(nodeCond.getResourceCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+ }
+ if (nodeCond.getAttributeCond() != null) {
+ query.append(getQuery(nodeCond.getAttributeCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+ }
+ if (nodeCond.getAnyCond() != null) {
+ query.append(getQuery(nodeCond.getAnyCond(),
+ nodeCond.getType() == SearchCond.Type.NOT_LEAF, parameters, type, svs));
+ }
+ break;
+
+ case AND:
+ query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
+ append(" AND any_id IN ( ").
+ append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
+ append(")");
+ break;
+
+ case OR:
+ query.append(getQuery(nodeCond.getLeftNodeCond(), parameters, type, svs)).
+ append(" OR any_id IN ( ").
+ append(getQuery(nodeCond.getRightNodeCond(), parameters, type, svs)).
+ append(")");
+ break;
+
+ default:
+ }
+
+ return query;
+ }
+
+ private String getQuery(final RelationshipCond cond, final boolean not, final List<Object> parameters,
+ final SearchSupport svs) {
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+
+ if (not) {
+ query.append("any_id NOT IN (");
+ } else {
+ query.append("any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id ").append("FROM ").
+ append(svs.relationship().name).append(" WHERE ").
+ append("right_anyObject_id=?").append(setParameter(parameters, cond.getAnyObjectKey())).
+ append(')');
+
+ return query.toString();
+ }
+
+ private String getQuery(final MembershipCond cond, final boolean not, final List<Object> parameters,
+ final SearchSupport svs) {
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+
+ if (not) {
+ query.append("any_id NOT IN (");
+ } else {
+ query.append("any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id ").append("FROM ").
+ append(svs.membership().name).append(" WHERE ").
+ append("group_id=?").append(setParameter(parameters, cond.getGroupKey())).
+ append(')');
+
+ if (not) {
+ query.append("AND any_id NOT IN (");
+ } else {
+ query.append("OR any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id ").append("FROM ").
+ append(svs.dyngroupmembership().name).append(" WHERE ").
+ append("group_id=?").append(setParameter(parameters, cond.getGroupKey())).
+ append(')');
+
+ return query.toString();
+ }
+
+ private String getQuery(final RoleCond cond, final boolean not, final List<Object> parameters,
+ final SearchSupport svs) {
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+
+ if (not) {
+ query.append("any_id NOT IN (");
+ } else {
+ query.append("any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id ").append("FROM ").
+ append(svs.role().name).append(" WHERE ").
+ append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
+ append(')');
+
+ if (not) {
+ query.append("AND any_id NOT IN (");
+ } else {
+ query.append("OR any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id ").append("FROM ").
+ append(svs.dynrolemembership().name).append(" WHERE ").
+ append("role_id=?").append(setParameter(parameters, cond.getRoleKey())).
+ append(')');
+
+ return query.toString();
+ }
+
+ private String getQuery(final ResourceCond cond, final boolean not, final List<Object> parameters,
+ final AnyTypeKind typeKind, final SearchSupport svs) {
+
+ final StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+
+ if (not) {
+ query.append("any_id NOT IN (");
+ } else {
+ query.append("any_id IN (");
+ }
+
+ query.append("SELECT DISTINCT any_id FROM ").
+ append(svs.resource().name).
+ append(" WHERE resource_name=?").
+ append(setParameter(parameters, cond.getResourceName()));
+
+ if (typeKind == AnyTypeKind.USER) {
+ query.append(" UNION SELECT DISTINCT any_id FROM ").
+ append(svs.groupResource().name).
+ append(" WHERE resource_name=?").
+ append(setParameter(parameters, cond.getResourceName()));
+ }
+
+ query.append(')');
+
+ return query.toString();
+ }
+
+ private void fillAttributeQuery(final StringBuilder query, final PlainAttrValue attrValue,
+ final PlainSchema schema, final AttributeCond cond, final boolean not,
+ final List<Object> parameters, final SearchSupport svs) {
+
+ String column = (cond instanceof AnyCond)
+ ? cond.getSchema()
+ : "' AND " + svs.fieldName(schema.getType());
+
+ switch (cond.getType()) {
+
+ case ISNULL:
+ query.append(column).append(not
+ ? " IS NOT NULL"
+ : " IS NULL");
+ break;
+
+ case ISNOTNULL:
+ query.append(column).append(not
+ ? " IS NULL"
+ : " IS NOT NULL");
+ break;
+
+ case LIKE:
+ if (schema.getType() == AttrSchemaType.String || schema.getType() == AttrSchemaType.Enum) {
+ query.append(column);
+ if (not) {
+ query.append(" NOT ");
+ }
+ query.append(" LIKE ?").append(setParameter(parameters, cond.getExpression()));
+ } else {
+ if (!(cond instanceof AnyCond)) {
+ query.append("' AND");
+ }
+ query.append(" 1=2");
+ LOG.error("LIKE is only compatible with string or enum schemas");
+ }
+ break;
+
+ case EQ:
+ query.append(column);
+ if (not) {
+ query.append("<>");
+ } else {
+ query.append('=');
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
+
+ case GE:
+ query.append(column);
+ if (not) {
+ query.append('<');
+ } else {
+ query.append(">=");
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
+
+ case GT:
+ query.append(column);
+ if (not) {
+ query.append("<=");
+ } else {
+ query.append('>');
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
+
+ case LE:
+ query.append(column);
+ if (not) {
+ query.append('>');
+ } else {
+ query.append("<=");
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
+
+ case LT:
+ query.append(column);
+ if (not) {
+ query.append(">=");
+ } else {
+ query.append('<');
+ }
+ query.append('?').append(setParameter(parameters, attrValue.getValue()));
+ break;
+
+ default:
+ }
+ }
+
+ private String getQuery(final AttributeCond cond, final boolean not, final List<Object> parameters,
+ final AnyTypeKind typeKind, final SearchSupport svs) {
+
+ AnyUtils attrUtils = anyUtilsFactory.getInstance(typeKind);
+
+ PlainSchema schema = schemaDAO.find(cond.getSchema());
+ if (schema == null) {
+ LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
+ return EMPTY_ATTR_QUERY;
+ }
+
+ PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+ try {
+ if (cond.getType() != AttributeCond.Type.LIKE && cond.getType() != AttributeCond.Type.ISNULL
+ && cond.getType() != AttributeCond.Type.ISNOTNULL) {
+
+ schema.getValidator().validate(cond.getExpression(), attrValue);
+ }
+ } catch (ValidationException e) {
+ LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
+ return EMPTY_ATTR_QUERY;
+ }
+
+ StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ");
+ if (cond.getType() == AttributeCond.Type.ISNOTNULL) {
+ query.append(svs.field().name).
+ append(" WHERE any_id NOT IN (SELECT any_id FROM ").
+ append(svs.nullAttr().name).
+ append(" WHERE schema_name='").append(schema.getKey()).append("')");
+ } else {
+ if (cond.getType() == AttributeCond.Type.ISNULL) {
+ query.append(svs.nullAttr().name).
+ append(" WHERE schema_name='").append(schema.getKey()).append("'");
+ } else {
+ if (schema.isUniqueConstraint()) {
+ query.append(svs.uniqueAttr().name);
+ } else {
+ query.append(svs.attr().name);
+ }
+ query.append(" WHERE schema_name='").append(schema.getKey());
+
+ fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
+ }
+ }
+
+ return query.toString();
+ }
+
+ @SuppressWarnings("rawtypes")
+ private String getQuery(final AnyCond cond, final boolean not, final List<Object> parameters,
+ final AnyTypeKind typeKind, final SearchSupport svs) {
+
+ AnyUtils attrUtils = anyUtilsFactory.getInstance(typeKind);
+
+ // Keeps track of difference between entity's getKey() and JPA @Id fields
+ if ("key".equals(cond.getSchema())) {
+ cond.setSchema("id");
+ }
+
+ Field subjectField = ReflectionUtils.findField(attrUtils.anyClass(), cond.getSchema());
+ if (subjectField == null) {
+ LOG.warn("Ignoring invalid schema '{}'", cond.getSchema());
+ return EMPTY_ATTR_QUERY;
+ }
+
+ PlainSchema schema = new JPAPlainSchema();
+ schema.setKey(subjectField.getName());
+ for (AttrSchemaType attrSchemaType : AttrSchemaType.values()) {
+ if (subjectField.getType().isAssignableFrom(attrSchemaType.getType())) {
+ schema.setType(attrSchemaType);
+ }
+ }
+
+ // Deal with subject Integer fields logically mapping to boolean values
+ // (JPAGroup.inheritPlainAttrs, for example)
+ boolean foundBooleanMin = false;
+ boolean foundBooleanMax = false;
+ if (Integer.class.equals(subjectField.getType())) {
+ for (Annotation annotation : subjectField.getAnnotations()) {
+ if (Min.class.equals(annotation.annotationType())) {
+ foundBooleanMin = ((Min) annotation).value() == 0;
+ } else if (Max.class.equals(annotation.annotationType())) {
+ foundBooleanMax = ((Max) annotation).value() == 1;
+ }
+ }
+ }
+ if (foundBooleanMin && foundBooleanMax) {
+ schema.setType(AttrSchemaType.Boolean);
+ }
+
+ // Deal with subject fields representing relationships to other entities
+ if (subjectField.getType().getAnnotation(Entity.class) != null) {
+ Method relMethod = null;
+ try {
+ relMethod = ClassUtils.getPublicMethod(subjectField.getType(), "getKey", new Class[0]);
+ } catch (Exception e) {
+ LOG.error("Could not find {}#getKey", subjectField.getType(), e);
+ }
+
+ if (relMethod != null) {
+ if (Long.class.isAssignableFrom(relMethod.getReturnType())) {
+ cond.setSchema(cond.getSchema() + "_id");
+ schema.setType(AttrSchemaType.Long);
+ }
+ if (String.class.isAssignableFrom(relMethod.getReturnType())) {
+ cond.setSchema(cond.getSchema() + "_name");
+ schema.setType(AttrSchemaType.String);
+ }
+ }
+ }
+
+ PlainAttrValue attrValue = attrUtils.newPlainAttrValue();
+ if (cond.getType() != AttributeCond.Type.LIKE
+ && cond.getType() != AttributeCond.Type.ISNULL
+ && cond.getType() != AttributeCond.Type.ISNOTNULL) {
+
+ try {
+ schema.getValidator().validate(cond.getExpression(), attrValue);
+ } catch (ValidationException e) {
+ LOG.error("Could not validate expression '" + cond.getExpression() + "'", e);
+ return EMPTY_ATTR_QUERY;
+ }
+ }
+
+ final StringBuilder query = new StringBuilder("SELECT DISTINCT any_id FROM ").
+ append(svs.field().name).append(" WHERE ");
+
+ fillAttributeQuery(query, attrValue, schema, cond, not, parameters, svs);
+
+ return query.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
new file mode 100644
index 0000000..4d82d31
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeClassDAO.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeClassDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyTypeClass;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyTypeClass;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAAnyTypeClassDAO extends AbstractDAO<AnyTypeClass, String> implements AnyTypeClassDAO {
+
+ @Override
+ public AnyTypeClass find(final String key) {
+ return entityManager.find(JPAAnyTypeClass.class, key);
+ }
+
+ @Override
+ public List<AnyTypeClass> findAll() {
+ TypedQuery<AnyTypeClass> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAAnyTypeClass.class.getSimpleName() + " e ", AnyTypeClass.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public AnyTypeClass save(final AnyTypeClass anyTypeClass) {
+ return entityManager.merge(anyTypeClass);
+ }
+
+ @Override
+ public void delete(final String key) {
+ AnyTypeClass anyTypeClass = find(key);
+ if (anyTypeClass == null) {
+ return;
+ }
+
+ entityManager.remove(anyTypeClass);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
new file mode 100644
index 0000000..bbbf859
--- /dev/null
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAnyTypeDAO.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
+import org.apache.syncope.core.persistence.api.dao.AnyTypeDAO;
+import org.apache.syncope.core.persistence.api.entity.AnyType;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyType;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAAnyTypeDAO extends AbstractDAO<AnyType, String> implements AnyTypeDAO {
+
+ @Override
+ public AnyType find(final String key) {
+ return entityManager.find(JPAAnyType.class, key);
+ }
+
+ private AnyType find(final AnyTypeKind typeKind) {
+ AnyType anyType = find(typeKind.name());
+ if (anyType == null) {
+ anyType = new JPAAnyType();
+ anyType.setKey(typeKind.name());
+ anyType.setKind(typeKind);
+ anyType = save(anyType);
+ }
+ return anyType;
+ }
+
+ @Transactional(readOnly = false)
+ @Override
+ public AnyType findUser() {
+ return find(AnyTypeKind.USER);
+ }
+
+ @Transactional(readOnly = false)
+ @Override
+ public AnyType findGroup() {
+ return find(AnyTypeKind.GROUP);
+ }
+
+ @Override
+ public List<AnyType> findAll() {
+ TypedQuery<AnyType> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAAnyType.class.getSimpleName() + " e ", AnyType.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public AnyType save(final AnyType anyType) {
+ return entityManager.merge(anyType);
+ }
+
+ @Override
+ public void delete(final String key) {
+ AnyType anyType = find(key);
+ if (anyType == null) {
+ return;
+ }
+
+ entityManager.remove(anyType);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
deleted file mode 100644
index 2b33178..0000000
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
+++ /dev/null
@@ -1,107 +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.core.persistence.jpa.dao;
-
-import java.util.Collections;
-import java.util.List;
-import javax.persistence.Query;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
-import org.apache.syncope.core.persistence.api.entity.AttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.Schema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.membership.MVirAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GDerAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GPlainAttrTemplate;
-import org.apache.syncope.core.persistence.api.entity.group.GVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGPlainAttrTemplate;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGVirAttrTemplate;
-import org.springframework.stereotype.Repository;
-import org.springframework.util.ReflectionUtils;
-
-@Repository
-public class JPAAttrTemplateDAO<S extends Schema>
- extends AbstractDAO<AttrTemplate<S>, Long> implements AttrTemplateDAO<S> {
-
- private <T extends AttrTemplate<S>> Class<? extends AbstractAttrTemplate<? extends Schema>> getJPAEntityReference(
- final Class<T> reference) {
-
- return MPlainAttrTemplate.class.isAssignableFrom(reference)
- ? JPAMPlainAttrTemplate.class
- : MDerAttrTemplate.class.isAssignableFrom(reference)
- ? JPAMDerAttrTemplate.class
- : MVirAttrTemplate.class.isAssignableFrom(reference)
- ? JPAMVirAttrTemplate.class
- : GPlainAttrTemplate.class.isAssignableFrom(reference)
- ? JPAGPlainAttrTemplate.class
- : GDerAttrTemplate.class.isAssignableFrom(reference)
- ? JPAGDerAttrTemplate.class
- : GVirAttrTemplate.class.isAssignableFrom(reference)
- ? JPAGVirAttrTemplate.class
- : null;
- }
-
- @Override
- public <T extends AttrTemplate<S>> T find(final Long key, final Class<T> reference) {
- return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T extends AttrTemplate<S>> List<Number> findBySchemaName(
- final String schemaName, final Class<T> reference) {
-
- Query query = null;
- try {
- query = entityManager.createNativeQuery("SELECT id FROM "
- + ReflectionUtils.findField(getJPAEntityReference(reference), "TABLE").get(null).toString()
- + " WHERE schema_name=?1");
- query.setParameter(1, schemaName);
- } catch (Exception e) {
- LOG.error("Unexpected exception", e);
- }
-
- return query == null ? Collections.<Number>emptyList() : query.getResultList();
- }
-
- @Override
- public <T extends AttrTemplate<S>> void delete(final Long key, final Class<T> reference) {
- T attrTemplate = find(key, reference);
- if (attrTemplate == null) {
- return;
- }
-
- delete(attrTemplate);
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T extends AttrTemplate<S>> void delete(final T attrTemplate) {
- if (attrTemplate.getOwner() != null) {
- attrTemplate.getOwner().getAttrTemplates(attrTemplate.getClass()).remove(attrTemplate);
- }
-
- entityManager.remove(attrTemplate);
- }
-}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
index 48e9f5e..7045a1a 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
@@ -18,15 +18,14 @@
*/
package org.apache.syncope.core.persistence.jpa.dao;
-import org.apache.syncope.common.lib.types.AttributableType;
import org.apache.syncope.core.persistence.api.dao.ConfDAO;
import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrUniqueValue;
import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
-import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
import org.apache.syncope.core.persistence.api.entity.conf.Conf;
import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
import org.apache.syncope.core.persistence.jpa.entity.conf.JPAConf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -41,9 +40,6 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
@Autowired
private PlainAttrDAO attrDAO;
- @Autowired
- private AttributableUtilsFactory attrUtilsFactory;
-
@Override
public Conf get() {
Conf instance = entityManager.find(JPAConf.class, 1L);
@@ -68,10 +64,19 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
public CPlainAttr find(final String key, final String defaultValue) {
CPlainAttr result = find(key);
if (result == null) {
- result = new JPACPlainAttr();
- result.setSchema(schemaDAO.find(key, CPlainSchema.class));
-
- result.addValue(defaultValue, attrUtilsFactory.getInstance(AttributableType.CONFIGURATION));
+ JPACPlainAttr newAttr = new JPACPlainAttr();
+ newAttr.setSchema(schemaDAO.find(key));
+
+ JPACPlainAttrValue attrValue;
+ if (newAttr.getSchema().isUniqueConstraint()) {
+ attrValue = new JPACPlainAttrValue();
+ ((PlainAttrUniqueValue) attrValue).setSchema(newAttr.getSchema());
+ } else {
+ attrValue = new JPACPlainAttrValue();
+ }
+ newAttr.add(defaultValue, attrValue);
+
+ result = newAttr;
}
return result;
@@ -85,11 +90,11 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
if (old != null && (!attr.getSchema().isUniqueConstraint()
|| (!attr.getUniqueValue().getStringValue().equals(old.getUniqueValue().getStringValue())))) {
- instance.removePlainAttr(old);
+ instance.remove(old);
attrDAO.delete(old.getKey(), CPlainAttr.class);
}
- instance.addPlainAttr(attr);
+ instance.add(attr);
attr.setOwner(instance);
return entityManager.merge(instance);
@@ -100,7 +105,7 @@ public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
Conf instance = get();
CPlainAttr attr = instance.getPlainAttr(key);
if (attr != null) {
- instance.removePlainAttr(attr);
+ instance.remove(attr);
instance = entityManager.merge(instance);
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
index e148b04..453c363 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -27,7 +27,7 @@ import org.apache.syncope.core.persistence.api.dao.ConnInstanceDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.entity.ConnInstance;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
import org.apache.syncope.core.persistence.jpa.entity.JPAConnInstance;
import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
import org.springframework.beans.factory.annotation.Autowired;
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
index ff32fb8..2162898 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
@@ -21,51 +21,51 @@ package org.apache.syncope.core.persistence.jpa.dao;
import java.util.List;
import javax.persistence.TypedQuery;
import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
-import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.Any;
import org.apache.syncope.core.persistence.api.entity.DerAttr;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerAttr;
+import org.apache.syncope.core.persistence.api.entity.anyobject.ADerAttr;
import org.apache.syncope.core.persistence.api.entity.group.GDerAttr;
import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
import org.apache.syncope.core.persistence.jpa.entity.AbstractDerAttr;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerAttr;
+import org.apache.syncope.core.persistence.jpa.entity.anyobject.JPAADerAttr;
import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerAttr;
import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerAttr;
import org.springframework.stereotype.Repository;
@Repository
-public class JPADerAttrDAO extends AbstractDAO<DerAttr, Long> implements DerAttrDAO {
+public class JPADerAttrDAO extends AbstractDAO<DerAttr<?>, Long> implements DerAttrDAO {
- public <T extends DerAttr> Class<? extends AbstractDerAttr> getJPAEntityReference(
+ public <T extends DerAttr<?>> Class<? extends AbstractDerAttr<?>> getJPAEntityReference(
final Class<T> reference) {
return GDerAttr.class.isAssignableFrom(reference)
? JPAGDerAttr.class
- : MDerAttr.class.isAssignableFrom(reference)
- ? JPAMDerAttr.class
+ : ADerAttr.class.isAssignableFrom(reference)
+ ? JPAADerAttr.class
: UDerAttr.class.isAssignableFrom(reference)
? JPAUDerAttr.class
: null;
}
@Override
- public <T extends DerAttr> T find(final Long key, final Class<T> reference) {
+ public <T extends DerAttr<?>> T find(final Long key, final Class<T> reference) {
return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
}
@Override
- public <T extends DerAttr> List<T> findAll(final Class<T> reference) {
+ public <T extends DerAttr<?>> List<T> findAll(final Class<T> reference) {
TypedQuery<T> query = entityManager.createQuery(
"SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
return query.getResultList();
}
@Override
- public <T extends DerAttr> T save(final T derAttr) {
+ public <T extends DerAttr<?>> T save(final T derAttr) {
return entityManager.merge(derAttr);
}
@Override
- public <T extends DerAttr> void delete(final Long key, final Class<T> reference) {
+ public <T extends DerAttr<?>> void delete(final Long key, final Class<T> reference) {
T derAttr = find(key, reference);
if (derAttr == null) {
return;
@@ -76,9 +76,9 @@ public class JPADerAttrDAO extends AbstractDAO<DerAttr, Long> implements DerAttr
@Override
@SuppressWarnings("unchecked")
- public <T extends DerAttr> void delete(final T derAttr) {
+ public <T extends DerAttr<?>> void delete(final T derAttr) {
if (derAttr.getOwner() != null) {
- ((Attributable<?, T, ?>) derAttr.getOwner()).removeDerAttr(derAttr);
+ ((Any<?, T, ?>) derAttr.getOwner()).remove(derAttr);
}
entityManager.remove(derAttr);
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
index be0ec94..c3c10bf 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -20,25 +20,16 @@ package org.apache.syncope.core.persistence.jpa.dao;
import java.util.List;
import javax.persistence.TypedQuery;
-import org.apache.commons.collections4.Closure;
-import org.apache.commons.collections4.CollectionUtils;
-import org.apache.syncope.common.lib.types.AttributableType;
-import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.core.persistence.api.dao.DerAttrDAO;
import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
-import org.apache.syncope.core.persistence.api.entity.AttributableUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtils;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
import org.apache.syncope.core.persistence.api.entity.DerAttr;
import org.apache.syncope.core.persistence.api.entity.DerSchema;
-import org.apache.syncope.core.persistence.api.entity.membership.MDerSchema;
-import org.apache.syncope.core.persistence.api.entity.group.GDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UDerAttr;
-import org.apache.syncope.core.persistence.api.entity.user.UDerSchema;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGDerSchema;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerSchema;
+import org.apache.syncope.core.persistence.jpa.entity.JPAAnyUtilsFactory;
+import org.apache.syncope.core.persistence.jpa.entity.JPADerSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -49,44 +40,25 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
private DerAttrDAO derAttrDAO;
@Autowired
- private AttrTemplateDAO<DerSchema> attrTemplateDAO;
-
- @Autowired
private ExternalResourceDAO resourceDAO;
- private <T extends DerSchema> Class<? extends AbstractDerSchema> getJPAEntityReference(final Class<T> reference) {
- return GDerSchema.class.isAssignableFrom(reference)
- ? JPAGDerSchema.class
- : MDerSchema.class.isAssignableFrom(reference)
- ? JPAMDerSchema.class
- : UDerSchema.class.isAssignableFrom(reference)
- ? JPAUDerSchema.class
- : null;
- }
-
@Override
- public <T extends DerSchema> T find(final String key, final Class<T> reference) {
- return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ public DerSchema find(final String key) {
+ return entityManager.find(JPADerSchema.class, key);
}
@Override
- public <T extends DerSchema> List<T> findAll(final Class<T> reference) {
- TypedQuery<T> query = entityManager.createQuery(
- "SELECT e FROM " + getJPAEntityReference(reference).getSimpleName() + " e", reference);
+ public List<DerSchema> findAll() {
+ TypedQuery<DerSchema> query = entityManager.createQuery(
+ "SELECT e FROM " + JPADerSchema.class.getSimpleName() + " e", DerSchema.class);
return query.getResultList();
}
@Override
- public <T extends DerAttr> List<T> findAttrs(final DerSchema schema, final Class<T> reference) {
+ public <T extends DerAttr<?>> List<T> findAttrs(final DerSchema schema, final Class<T> reference) {
final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
append(((JPADerAttrDAO) derAttrDAO).getJPAEntityReference(reference).getSimpleName()).
- append(" e WHERE e.");
- if (UDerAttr.class.isAssignableFrom(reference)) {
- queryString.append("derSchema");
- } else {
- queryString.append("template.schema");
- }
- queryString.append("=:schema");
+ append(" e WHERE e.schema=:schema");
TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
query.setParameter("schema", schema);
@@ -95,42 +67,28 @@ public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements D
}
@Override
- public <T extends DerSchema> T save(final T derSchema) {
+ public DerSchema save(final DerSchema derSchema) {
return entityManager.merge(derSchema);
}
@Override
- @SuppressWarnings("unchecked")
- public void delete(final String key, final AttributableUtils attributableUtil) {
- final DerSchema schema = find(key, attributableUtil.derSchemaClass());
+ public void delete(final String key) {
+ final DerSchema schema = find(key);
if (schema == null) {
return;
}
- CollectionUtils.forAllDo(findAttrs(schema, attributableUtil.derAttrClass()), new Closure<DerAttr>() {
+ AnyUtilsFactory anyUtilsFactory = new JPAAnyUtilsFactory();
+ for (AnyTypeKind anyTypeKind : AnyTypeKind.values()) {
+ AnyUtils anyUtils = anyUtilsFactory.getInstance(anyTypeKind);
- @Override
- public void execute(final DerAttr input) {
- derAttrDAO.delete(input.getKey(), attributableUtil.derAttrClass());
+ for (DerAttr<?> attr : findAttrs(schema, anyUtils.derAttrClass())) {
+ derAttrDAO.delete(attr.getKey(), anyUtils.derAttrClass());
}
- });
-
- if (attributableUtil.getType() != AttributableType.USER) {
- CollectionUtils.forAllDo(attrTemplateDAO.
- findBySchemaName(schema.getKey(), attributableUtil.derAttrTemplateClass()).iterator(),
- new Closure<Number>() {
-
- @Override
- public void execute(final Number input) {
- attrTemplateDAO.delete(input.longValue(), attributableUtil.derAttrTemplateClass());
- }
-
- });
+ resourceDAO.deleteMapping(key, anyUtils.derIntMappingType());
}
- resourceDAO.deleteMapping(key, attributableUtil.derIntMappingType(), UMappingItem.class);
-
entityManager.remove(schema);
}
}
http://git-wip-us.apache.org/repos/asf/syncope/blob/081d9a04/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
index 70f00f7..b13a8bd 100644
--- a/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
+++ b/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -25,6 +25,7 @@ import javax.persistence.TypedQuery;
import org.apache.syncope.common.lib.types.IntMappingType;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.types.TaskType;
+import org.apache.syncope.core.persistence.api.dao.AnyObjectDAO;
import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
import org.apache.syncope.core.persistence.api.dao.NotFoundException;
import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
@@ -32,17 +33,17 @@ import org.apache.syncope.core.persistence.api.dao.GroupDAO;
import org.apache.syncope.core.persistence.api.dao.TaskDAO;
import org.apache.syncope.core.persistence.api.dao.UserDAO;
import org.apache.syncope.core.persistence.api.entity.AccountPolicy;
-import org.apache.syncope.core.persistence.api.entity.ExternalResource;
-import org.apache.syncope.core.persistence.api.entity.Mapping;
-import org.apache.syncope.core.persistence.api.entity.MappingItem;
+import org.apache.syncope.core.persistence.api.entity.AnyUtilsFactory;
+import org.apache.syncope.core.persistence.api.entity.resource.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.resource.MappingItem;
import org.apache.syncope.core.persistence.api.entity.Policy;
+import org.apache.syncope.core.persistence.api.entity.anyobject.AnyObject;
import org.apache.syncope.core.persistence.api.entity.group.Group;
-import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.core.persistence.api.entity.resource.Provision;
import org.apache.syncope.core.persistence.api.entity.user.User;
-import org.apache.syncope.core.persistence.jpa.entity.AbstractMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.JPAExternalResource;
-import org.apache.syncope.core.persistence.jpa.entity.group.JPAGMappingItem;
-import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAExternalResource;
+import org.apache.syncope.core.persistence.jpa.entity.resource.JPAMapping;
import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@@ -55,6 +56,9 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
private TaskDAO taskDAO;
@Autowired
+ private AnyObjectDAO anyObjectDAO;
+
+ @Autowired
private UserDAO userDAO;
@Autowired
@@ -66,6 +70,9 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
@Autowired
private ConnectorRegistry connRegistry;
+ @Autowired
+ private AnyUtilsFactory anyUtilsFactory;
+
@Override
public ExternalResource find(final String name) {
return entityManager.find(JPAExternalResource.class, name);
@@ -146,33 +153,25 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
@Override
@SuppressWarnings("unchecked")
- public <T extends MappingItem> void deleteMapping(
- final String intAttrName, final IntMappingType intMappingType, final Class<T> reference) {
-
+ public void deleteMapping(final String intAttrName, final IntMappingType intMappingType) {
if (IntMappingType.getEmbedded().contains(intMappingType)) {
return;
}
- Class<? extends AbstractMappingItem> jpaRef = reference.equals(UMappingItem.class)
- ? JPAUMappingItem.class
- : JPAGMappingItem.class;
-
- TypedQuery<T> query = entityManager.createQuery("SELECT m FROM " + jpaRef.getSimpleName()
- + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", reference);
+ TypedQuery<MappingItem> query = entityManager.createQuery(
+ "SELECT m FROM " + JPAMappingItem.class.getSimpleName()
+ + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", MappingItem.class);
query.setParameter("intAttrName", intAttrName);
query.setParameter("intMappingType", intMappingType);
- Set<Long> itemIds = new HashSet<>();
- for (T item : query.getResultList()) {
- itemIds.add(item.getKey());
+ Set<Long> itemKeys = new HashSet<>();
+ for (MappingItem item : query.getResultList()) {
+ itemKeys.add(item.getKey());
}
- Class<?> mappingRef = null;
- for (Long itemId : itemIds) {
- T item = (T) entityManager.find(jpaRef, itemId);
+ for (Long itemKey : itemKeys) {
+ MappingItem item = entityManager.find(JPAMappingItem.class, itemKey);
if (item != null) {
- mappingRef = item.getMapping().getClass();
-
- ((Mapping<T>) item.getMapping()).removeItem(item);
+ item.getMapping().remove(item);
item.setMapping(null);
entityManager.remove(item);
@@ -180,10 +179,8 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
}
// Make empty query cache for *MappingItem and related *Mapping
- entityManager.getEntityManagerFactory().getCache().evict(jpaRef);
- if (mappingRef != null) {
- entityManager.getEntityManagerFactory().getCache().evict(mappingRef);
- }
+ entityManager.getEntityManagerFactory().getCache().evict(JPAMappingItem.class);
+ entityManager.getEntityManagerFactory().getCache().evict(JPAMapping.class);
}
@Override
@@ -197,11 +194,14 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
taskDAO.deleteAll(resource, TaskType.SYNCHRONIZATION);
taskDAO.deleteAll(resource, TaskType.PUSH);
+ for (AnyObject anyObject : anyObjectDAO.findByResource(resource)) {
+ anyObject.remove(resource);
+ }
for (User user : userDAO.findByResource(resource)) {
- user.removeResource(resource);
+ user.remove(resource);
}
for (Group group : groupDAO.findByResource(resource)) {
- group.removeResource(resource);
+ group.remove(resource);
}
for (AccountPolicy policy : policyDAO.findByResource(resource)) {
policy.removeResource(resource);
@@ -214,21 +214,13 @@ public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String
}
resource.setConnector(null);
- if (resource.getUmapping() != null) {
- for (MappingItem item : resource.getUmapping().getItems()) {
- item.setMapping(null);
- }
- resource.getUmapping().getItems().clear();
- resource.getUmapping().setResource(null);
- resource.setUmapping(null);
- }
- if (resource.getGmapping() != null) {
- for (MappingItem item : resource.getGmapping().getItems()) {
+ for (Provision provision : resource.getProvisions()) {
+ for (MappingItem item : provision.getMapping().getItems()) {
item.setMapping(null);
}
- resource.getGmapping().getItems().clear();
- resource.getGmapping().setResource(null);
- resource.setGmapping(null);
+ provision.getMapping().getItems().clear();
+ provision.setMapping(null);
+ provision.setResource(null);
}
entityManager.remove(resource);