You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/12 10:14:43 UTC
[38/54] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Renaming
'server' after 'core',
to provide continuity with older releases (especially for archetype)
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
new file mode 100644
index 0000000..2bf2b80
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractDAO.java
@@ -0,0 +1,117 @@
+/*
+ * 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.CacheRetrieveMode;
+import javax.persistence.CacheStoreMode;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.dao.DAO;
+import org.apache.syncope.core.persistence.api.dao.search.OrderByClause;
+import org.apache.syncope.core.persistence.api.entity.Entity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.ReflectionUtils;
+
+@Configurable
+public abstract class AbstractDAO<E extends Entity<KEY>, KEY> implements DAO<E, KEY> {
+
+ /**
+ * Logger.
+ */
+ protected static final Logger LOG = LoggerFactory.getLogger(DAO.class);
+
+ private static final String CACHE_STORE_MODE = "javax.persistence.cache.storeMode";
+
+ private static final String CACHE_RETRIEVE_MODE = "javax.persistence.cache.retrieveMode";
+
+ @Value("#{entityManager}")
+ @PersistenceContext(type = PersistenceContextType.TRANSACTION)
+ protected EntityManager entityManager;
+
+ protected CacheRetrieveMode getCacheRetrieveMode() {
+ return entityManager.getProperties().containsKey(CACHE_RETRIEVE_MODE)
+ ? (CacheRetrieveMode) entityManager.getProperties().get(CACHE_RETRIEVE_MODE)
+ : CacheRetrieveMode.BYPASS;
+ }
+
+ protected void setCacheRetrieveMode(final CacheRetrieveMode retrieveMode) {
+ if (retrieveMode != null) {
+ entityManager.getProperties().put(CACHE_RETRIEVE_MODE, retrieveMode);
+ }
+ }
+
+ protected CacheStoreMode getCacheStoreMode() {
+ return entityManager.getProperties().containsKey(CACHE_STORE_MODE)
+ ? (CacheStoreMode) entityManager.getProperties().get(CACHE_STORE_MODE)
+ : CacheStoreMode.BYPASS;
+ }
+
+ protected void setCacheStoreMode(final CacheStoreMode storeMode) {
+ if (storeMode != null) {
+ entityManager.getProperties().put(CACHE_STORE_MODE, storeMode);
+ }
+ }
+
+ protected String toOrderByStatement(final Class<? extends Entity<KEY>> beanClass, final String prefix,
+ final List<OrderByClause> orderByClauses) {
+
+ StringBuilder statement = new StringBuilder();
+
+ for (OrderByClause clause : orderByClauses) {
+ String field = clause.getField().trim();
+ if (ReflectionUtils.findField(beanClass, field) != null) {
+ if (StringUtils.isNotBlank(prefix)) {
+ statement.append(prefix).append('.');
+ }
+ statement.append(field).append(' ').append(clause.getDirection().name());
+ }
+ }
+
+ if (statement.length() > 0) {
+ statement.insert(0, "ORDER BY ");
+ }
+ return statement.toString();
+ }
+
+ @Override
+ public void refresh(final E entity) {
+ entityManager.refresh(entity);
+ }
+
+ @Override
+ public void detach(final E entity) {
+ entityManager.detach(entity);
+ }
+
+ @Override
+ public void flush() {
+ entityManager.flush();
+ }
+
+ @Override
+ public void clear() {
+ entityManager.clear();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
new file mode 100644
index 0000000..1096b50
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/AbstractSubjectDAO.java
@@ -0,0 +1,347 @@
+/*
+ * 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.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import javax.persistence.Query;
+import javax.persistence.TemporalType;
+import org.apache.commons.jexl2.parser.Parser;
+import org.apache.commons.jexl2.parser.ParserConstants;
+import org.apache.commons.jexl2.parser.Token;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.core.persistence.api.dao.DerSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.PlainSchemaDAO;
+import org.apache.syncope.core.persistence.api.dao.SubjectDAO;
+import org.apache.syncope.core.persistence.api.entity.AttributableUtil;
+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.ExternalResource;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+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.Subject;
+import org.apache.syncope.core.persistence.api.entity.VirAttr;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.springframework.beans.factory.annotation.Autowired;
+
+abstract class AbstractSubjectDAO<P extends PlainAttr, D extends DerAttr, V extends VirAttr>
+ extends AbstractDAO<Subject<P, D, V>, Long> implements SubjectDAO<P, D, V> {
+
+ @Autowired
+ protected PlainSchemaDAO plainSchemaDAO;
+
+ @Autowired
+ protected DerSchemaDAO derSchemaDAO;
+
+ /**
+ * Split an attribute value recurring on provided literals/tokens.
+ *
+ * @param attrValue value to be split
+ * @param literals literals/tokens
+ * @return split value
+ */
+ private List<String> split(final String attrValue, final List<String> literals) {
+ final List<String> attrValues = new ArrayList<>();
+
+ if (literals.isEmpty()) {
+ attrValues.add(attrValue);
+ } else {
+ for (String token : attrValue.split(Pattern.quote(literals.get(0)))) {
+ attrValues.addAll(split(token, literals.subList(1, literals.size())));
+ }
+ }
+
+ return attrValues;
+ }
+
+ /**
+ * Generate one where clause for each different attribute schema into the derived schema expression provided.
+ *
+ * @param expression derived schema expression
+ * @param value derived attribute value
+ * @param attrUtil USER / ROLE
+ * @return where clauses to use to build the query
+ */
+ private Set<String> getWhereClause(final String expression, final String value, final AttributableUtil attrUtil) {
+ final Parser parser = new Parser(new StringReader(expression));
+
+ // Schema names
+ final List<String> identifiers = new ArrayList<>();
+
+ // Literals
+ final List<String> literals = new ArrayList<>();
+
+ // Get schema names and literals
+ Token token;
+ while ((token = parser.getNextToken()) != null && StringUtils.isNotBlank(token.toString())) {
+ if (token.kind == ParserConstants.STRING_LITERAL) {
+ literals.add(token.toString().substring(1, token.toString().length() - 1));
+ }
+
+ if (token.kind == ParserConstants.IDENTIFIER) {
+ identifiers.add(token.toString());
+ }
+ }
+
+ // Sort literals in order to process later literals included into others
+ Collections.sort(literals, new Comparator<String>() {
+
+ @Override
+ public int compare(final String t, final String t1) {
+ if (t == null && t1 == null) {
+ return 0;
+ } else if (t != null && t1 == null) {
+ return -1;
+ } else if (t == null && t1 != null) {
+ return 1;
+ } else if (t.length() == t1.length()) {
+ return 0;
+ } else if (t.length() > t1.length()) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ });
+
+ // Split value on provided literals
+ final List<String> attrValues = split(value, literals);
+
+ if (attrValues.size() != identifiers.size()) {
+ LOG.error("Ambiguous JEXL expression resolution.");
+ throw new IllegalArgumentException("literals and values have different size");
+ }
+
+ // clauses to be used with INTERSECTed queries
+ final Set<String> clauses = new HashSet<>();
+
+ // builder to build the clauses
+ final StringBuilder bld = new StringBuilder();
+
+ // Contains used identifiers in order to avoid replications
+ final Set<String> used = new HashSet<>();
+
+ // Create several clauses: one for eanch identifiers
+ for (int i = 0; i < identifiers.size(); i++) {
+ if (!used.contains(identifiers.get(i))) {
+
+ // verify schema existence and get schema type
+ PlainSchema schema = plainSchemaDAO.find(identifiers.get(i), attrUtil.plainSchemaClass());
+ if (schema == null) {
+ LOG.error("Invalid schema name '{}'", identifiers.get(i));
+ throw new IllegalArgumentException("Invalid schema name " + identifiers.get(i));
+ }
+
+ // clear builder
+ bld.delete(0, bld.length());
+
+ bld.append("(");
+
+ // set schema name
+ bld.append("s.name = '").append(identifiers.get(i)).append("'");
+
+ bld.append(" AND ");
+
+ bld.append("s.name = a.schema_name").append(" AND ");
+
+ bld.append("a.id = v.attribute_id");
+
+ bld.append(" AND ");
+
+ // use a value clause different for eanch different schema type
+ switch (schema.getType()) {
+ case Boolean:
+ bld.append("v.booleanValue = '").append(attrValues.get(i)).append("'");
+ break;
+ case Long:
+ bld.append("v.longValue = ").append(attrValues.get(i));
+ break;
+ case Double:
+ bld.append("v.doubleValue = ").append(attrValues.get(i));
+ break;
+ case Date:
+ bld.append("v.dateValue = '").append(attrValues.get(i)).append("'");
+ break;
+ default:
+ bld.append("v.stringValue = '").append(attrValues.get(i)).append("'");
+ }
+
+ bld.append(")");
+
+ used.add(identifiers.get(i));
+
+ clauses.add(bld.toString());
+ }
+ }
+
+ LOG.debug("Generated where clauses {}", clauses);
+
+ return clauses;
+ }
+
+ protected abstract Subject<P, D, V> findInternal(Long key);
+
+ private Query findByAttrValueQuery(final String entityName) {
+ return entityManager.createQuery("SELECT e FROM " + entityName + " e"
+ + " WHERE e.attribute.schema.name = :schemaName AND (e.stringValue IS NOT NULL"
+ + " AND e.stringValue = :stringValue)"
+ + " OR (e.booleanValue IS NOT NULL AND e.booleanValue = :booleanValue)"
+ + " OR (e.dateValue IS NOT NULL AND e.dateValue = :dateValue)"
+ + " OR (e.longValue IS NOT NULL AND e.longValue = :longValue)"
+ + " OR (e.doubleValue IS NOT NULL AND e.doubleValue = :doubleValue)");
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<? extends Subject<P, D, V>> findByAttrValue(
+ final String schemaName, final PlainAttrValue attrValue, final AttributableUtil attrUtil) {
+
+ PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtil.plainSchemaClass());
+ if (schema == null) {
+ LOG.error("Invalid schema name '{}'", schemaName);
+ return Collections.<Subject<P, D, V>>emptyList();
+ }
+
+ final String entityName = schema.isUniqueConstraint()
+ ? attrUtil.plainAttrUniqueValueClass().getName()
+ : attrUtil.plainAttrValueClass().getName();
+
+ Query query = findByAttrValueQuery(entityName);
+
+ query.setParameter("schemaName", schemaName);
+ query.setParameter("stringValue", attrValue.getStringValue());
+ query.setParameter("booleanValue", attrValue.getBooleanValue() == null
+ ? null
+ : ((AbstractPlainAttrValue) attrValue).getBooleanAsInteger(attrValue.getBooleanValue()));
+ if (attrValue.getDateValue() == null) {
+ query.setParameter("dateValue", null);
+ } else {
+ query.setParameter("dateValue", attrValue.getDateValue(), TemporalType.TIMESTAMP);
+ }
+ query.setParameter("longValue", attrValue.getLongValue());
+ query.setParameter("doubleValue", attrValue.getDoubleValue());
+
+ List<Subject<P, D, V>> result = new ArrayList<>();
+ for (PlainAttrValue value : (List<PlainAttrValue>) query.getResultList()) {
+ Subject<P, D, V> subject = (Subject<P, D, V>) value.getAttr().getOwner();
+ if (!result.contains(subject)) {
+ result.add(subject);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ public Subject<P, D, V> findByAttrUniqueValue(
+ final String schemaName, final PlainAttrValue attrUniqueValue, final AttributableUtil attrUtil) {
+
+ PlainSchema schema = plainSchemaDAO.find(schemaName, attrUtil.plainSchemaClass());
+ if (schema == null) {
+ LOG.error("Invalid schema name '{}'", schemaName);
+ return null;
+ }
+ if (!schema.isUniqueConstraint()) {
+ LOG.error("This schema has not unique constraint: '{}'", schemaName);
+ return null;
+ }
+
+ List<? extends Subject<P, D, V>> result = findByAttrValue(schemaName, attrUniqueValue, attrUtil);
+ return result.isEmpty()
+ ? null
+ : result.iterator().next();
+ }
+
+ /**
+ * Find users / roles by derived attribute value. This method could fail if one or more string literals contained
+ * into the derived attribute value provided derive from identifier (schema name) replacement. When you are going to
+ * specify a derived attribute expression you must be quite sure that string literals used to build the expression
+ * cannot be found into the attribute values used to replace attribute schema names used as identifiers.
+ *
+ * @param schemaName derived schema name
+ * @param value derived attribute value
+ * @param attrUtil AttributableUtil
+ * @return list of users / roles
+ */
+ @Override
+ public List<? extends Subject<P, D, V>> findByDerAttrValue(
+ final String schemaName, final String value, final AttributableUtil attrUtil) {
+
+ DerSchema schema = derSchemaDAO.find(schemaName, attrUtil.derSchemaClass());
+ if (schema == null) {
+ LOG.error("Invalid schema name '{}'", schemaName);
+ return Collections.<Subject<P, D, V>>emptyList();
+ }
+
+ // query string
+ final StringBuilder querystring = new StringBuilder();
+
+ boolean subquery = false;
+ for (String clause : getWhereClause(schema.getExpression(), value, attrUtil)) {
+ if (querystring.length() > 0) {
+ subquery = true;
+ querystring.append(" AND a.owner_id IN ( ");
+ }
+
+ querystring.append("SELECT a.owner_id ").
+ append("FROM ").append(attrUtil.plainAttrClass().getSimpleName().substring(3)).append(" a, ").
+ append(attrUtil.plainAttrValueClass().getSimpleName().substring(3)).append(" v, ").
+ append(attrUtil.plainSchemaClass().getSimpleName().substring(3)).append(" s ").
+ append("WHERE ").append(clause);
+
+ if (subquery) {
+ querystring.append(')');
+ }
+ }
+
+ LOG.debug("Execute query {}", querystring);
+
+ final Query query = entityManager.createNativeQuery(querystring.toString());
+
+ final List<Subject<P, D, V>> result = new ArrayList<>();
+ for (Object userId : query.getResultList()) {
+ Subject<P, D, V> subject = findInternal(Long.parseLong(userId.toString()));
+ if (!result.contains(subject)) {
+ result.add(subject);
+ }
+ }
+
+ return result;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<? extends Subject<P, D, V>> findByResource(
+ final ExternalResource resource, final AttributableUtil attrUtil) {
+
+ Query query = entityManager.createQuery(
+ "SELECT e FROM " + attrUtil.attributableClass().getSimpleName() + " e "
+ + "WHERE :resource MEMBER OF e.resources");
+ query.setParameter("resource", resource);
+
+ return query.getResultList();
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
new file mode 100644
index 0000000..233257b
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAAttrTemplateDAO.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.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.role.RDerAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrTemplate;
+import org.apache.syncope.core.persistence.api.entity.role.RVirAttrTemplate;
+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.role.JPARDerAttrTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttrTemplate;
+import org.apache.syncope.core.persistence.jpa.entity.role.JPARVirAttrTemplate;
+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
+ : RPlainAttrTemplate.class.isAssignableFrom(reference)
+ ? JPARPlainAttrTemplate.class
+ : RDerAttrTemplate.class.isAssignableFrom(reference)
+ ? JPARDerAttrTemplate.class
+ : RVirAttrTemplate.class.isAssignableFrom(reference)
+ ? JPARVirAttrTemplate.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/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
new file mode 100644
index 0000000..e7db7cf
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConfDAO.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.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.AttributableUtilFactory;
+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.JPAConf;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAConfDAO extends AbstractDAO<Conf, Long> implements ConfDAO {
+
+ @Autowired
+ private PlainSchemaDAO schemaDAO;
+
+ @Autowired
+ private PlainAttrDAO attrDAO;
+
+ @Autowired
+ private AttributableUtilFactory attrUtilFactory;
+
+ @Override
+ public Conf get() {
+ Conf instance = entityManager.find(JPAConf.class, 1L);
+ if (instance == null) {
+ instance = new JPAConf();
+ instance.setKey(1L);
+
+ instance = entityManager.merge(instance);
+ }
+
+ return instance;
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ public CPlainAttr find(final String key) {
+ return get().getPlainAttr(key);
+ }
+
+ @Transactional(readOnly = true)
+ @Override
+ 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, attrUtilFactory.getInstance(AttributableType.CONFIGURATION));
+ }
+
+ return result;
+ }
+
+ @Override
+ public Conf save(final CPlainAttr attr) {
+ Conf instance = get();
+
+ CPlainAttr old = instance.getPlainAttr(attr.getSchema().getKey());
+ if (old != null && (!attr.getSchema().isUniqueConstraint()
+ || (!attr.getUniqueValue().getStringValue().equals(old.getUniqueValue().getStringValue())))) {
+
+ instance.removePlainAttr(old);
+ attrDAO.delete(old.getKey(), CPlainAttr.class);
+ }
+
+ instance.addPlainAttr(attr);
+ attr.setOwner(instance);
+
+ return entityManager.merge(instance);
+ }
+
+ @Override
+ public Conf delete(final String key) {
+ Conf instance = get();
+ CPlainAttr attr = instance.getPlainAttr(key);
+ if (attr != null) {
+ instance.removePlainAttr(attr);
+ instance = entityManager.merge(instance);
+ }
+
+ return instance;
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
new file mode 100644
index 0000000..8d6fcac
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAConnInstanceDAO.java
@@ -0,0 +1,90 @@
+/*
+ * 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.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.TypedQuery;
+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.jpa.entity.JPAConnInstance;
+import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAConnInstanceDAO extends AbstractDAO<ConnInstance, Long> implements ConnInstanceDAO {
+
+ @Autowired
+ private ExternalResourceDAO resourceDAO;
+
+ @Autowired
+ private ConnectorRegistry connRegistry;
+
+ @Override
+ public ConnInstance find(final Long key) {
+ return entityManager.find(JPAConnInstance.class, key);
+ }
+
+ @Override
+ public List<ConnInstance> findAll() {
+ TypedQuery<ConnInstance> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAConnInstance.class.getSimpleName() + " e", ConnInstance.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public ConnInstance save(final ConnInstance connector) {
+ final ConnInstance merged = entityManager.merge(connector);
+
+ for (ExternalResource resource : merged.getResources()) {
+ try {
+ connRegistry.registerConnector(resource);
+ } catch (NotFoundException e) {
+ LOG.error("While registering connector for resource", e);
+ }
+ }
+
+ return merged;
+ }
+
+ @Override
+ public void delete(final Long key) {
+ ConnInstance connInstance = find(key);
+ if (connInstance == null) {
+ return;
+ }
+
+ Set<String> resourceNames = new HashSet<>(connInstance.getResources().size());
+ for (ExternalResource resource : connInstance.getResources()) {
+ resourceNames.add(resource.getKey());
+ }
+ for (String resourceName : resourceNames) {
+ resourceDAO.delete(resourceName);
+ }
+
+ entityManager.remove(connInstance);
+
+ connRegistry.unregisterConnector(key.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
new file mode 100644
index 0000000..daf0cb1
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerAttrDAO.java
@@ -0,0 +1,86 @@
+/*
+ * 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.DerAttrDAO;
+import org.apache.syncope.core.persistence.api.entity.Attributable;
+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.role.RDerAttr;
+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.role.JPARDerAttr;
+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 <T extends DerAttr> Class<? extends AbstractDerAttr> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return RDerAttr.class.isAssignableFrom(reference)
+ ? JPARDerAttr.class
+ : MDerAttr.class.isAssignableFrom(reference)
+ ? JPAMDerAttr.class
+ : UDerAttr.class.isAssignableFrom(reference)
+ ? JPAUDerAttr.class
+ : null;
+ }
+
+ @Override
+ 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) {
+ 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) {
+ return entityManager.merge(derAttr);
+ }
+
+ @Override
+ public <T extends DerAttr> void delete(final Long key, final Class<T> reference) {
+ T derAttr = find(key, reference);
+ if (derAttr == null) {
+ return;
+ }
+
+ delete(derAttr);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends DerAttr> void delete(final T derAttr) {
+ if (derAttr.getOwner() != null) {
+ ((Attributable<?, T, ?>) derAttr.getOwner()).removeDerAttr(derAttr);
+ }
+
+ entityManager.remove(derAttr);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
new file mode 100644
index 0000000..985851e
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPADerSchemaDAO.java
@@ -0,0 +1,132 @@
+/*
+ * 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.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+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.AttributableUtil;
+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.role.RDerSchema;
+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.role.JPARDerSchema;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUDerSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPADerSchemaDAO extends AbstractDAO<DerSchema, String> implements DerSchemaDAO {
+
+ @Autowired
+ 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 RDerSchema.class.isAssignableFrom(reference)
+ ? JPARDerSchema.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));
+ }
+
+ @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);
+ return query.getResultList();
+ }
+
+ @Override
+ 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");
+
+ TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+ query.setParameter("schema", schema);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public <T extends DerSchema> T save(final T derSchema) {
+ return entityManager.merge(derSchema);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void delete(final String key, final AttributableUtil attributableUtil) {
+ final DerSchema schema = find(key, attributableUtil.derSchemaClass());
+ if (schema == null) {
+ return;
+ }
+
+ final Set<Long> attrIds = new HashSet<>();
+ for (DerAttr attr : findAttrs(schema, attributableUtil.derAttrClass())) {
+ attrIds.add(attr.getKey());
+ }
+ for (Long attrId : attrIds) {
+ derAttrDAO.delete(attrId, attributableUtil.derAttrClass());
+ }
+
+ if (attributableUtil.getType() != AttributableType.USER) {
+ for (Iterator<Number> it = attrTemplateDAO.
+ findBySchemaName(schema.getKey(), attributableUtil.derAttrTemplateClass()).iterator();
+ it.hasNext();) {
+
+ attrTemplateDAO.delete(it.next().longValue(), attributableUtil.derAttrTemplateClass());
+ }
+ }
+
+ resourceDAO.deleteMapping(key, attributableUtil.derIntMappingType(), UMappingItem.class);
+
+ entityManager.remove(schema);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
new file mode 100644
index 0000000..bc74b30
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAEntitlementDAO.java
@@ -0,0 +1,88 @@
+/*
+ * 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.RoleEntitlementUtil;
+import org.apache.syncope.core.persistence.api.dao.EntitlementDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+import org.apache.syncope.core.persistence.api.entity.Entitlement;
+import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.jpa.entity.JPAEntitlement;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAEntitlementDAO extends AbstractDAO<Entitlement, String> implements EntitlementDAO {
+
+ @Autowired
+ private RoleDAO roleDAO;
+
+ @Override
+ public Entitlement find(final String name) {
+ return entityManager.find(JPAEntitlement.class, name);
+ }
+
+ @Override
+ public List<Entitlement> findAll() {
+ TypedQuery<Entitlement> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAEntitlement.class.getSimpleName() + " e", Entitlement.class);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public Entitlement save(final Entitlement entitlement) {
+ return entityManager.merge(entitlement);
+ }
+
+ @Override
+ public Entitlement saveRoleEntitlement(final Role role) {
+ Entitlement roleEnt = new JPAEntitlement();
+ roleEnt.setKey(RoleEntitlementUtil.getEntitlementNameFromRoleKey(role.getKey()));
+ roleEnt.setDescription("Entitlement for managing role " + role.getKey());
+
+ return save(roleEnt);
+ }
+
+ @Override
+ public void delete(final String name) {
+ Entitlement entitlement = find(name);
+ if (entitlement == null) {
+ return;
+ }
+
+ delete(entitlement);
+ }
+
+ @Override
+ public void delete(final Entitlement entitlement) {
+ if (entitlement == null) {
+ return;
+ }
+
+ for (Role role : roleDAO.findByEntitlement(entitlement)) {
+ role.removeEntitlement(entitlement);
+ roleDAO.save(role);
+ }
+
+ entityManager.remove(entitlement);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
new file mode 100644
index 0000000..9bc2a25
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAExternalResourceDAO.java
@@ -0,0 +1,254 @@
+/*
+ * 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.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.NoResultException;
+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.ExternalResourceDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.PolicyDAO;
+import org.apache.syncope.core.persistence.api.dao.RoleDAO;
+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.Policy;
+import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.task.PropagationTask;
+import org.apache.syncope.core.persistence.api.entity.task.PushTask;
+import org.apache.syncope.core.persistence.api.entity.task.SyncTask;
+import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+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.role.JPARMappingItem;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUMappingItem;
+import org.apache.syncope.core.provisioning.api.ConnectorRegistry;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+@Repository
+public class JPAExternalResourceDAO extends AbstractDAO<ExternalResource, String> implements ExternalResourceDAO {
+
+ @Autowired
+ private TaskDAO taskDAO;
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Autowired
+ private RoleDAO roleDAO;
+
+ @Autowired
+ private PolicyDAO policyDAO;
+
+ @Autowired
+ private ConnectorRegistry connRegistry;
+
+ @Override
+ public ExternalResource find(final String name) {
+ TypedQuery<ExternalResource> query = entityManager.createQuery("SELECT e FROM "
+ + JPAExternalResource.class.getSimpleName() + " e WHERE e.name = :name", ExternalResource.class);
+ query.setParameter("name", name);
+
+ ExternalResource result = null;
+ try {
+ result = query.getSingleResult();
+ } catch (NoResultException e) {
+ LOG.debug("No resource found with name {}", name, e);
+ }
+
+ return result;
+ }
+
+ private StringBuilder getByPolicyQuery(final PolicyType type) {
+ StringBuilder query = new StringBuilder("SELECT e FROM ").
+ append(JPAExternalResource.class.getSimpleName()).
+ append(" e WHERE e.");
+ switch (type) {
+ case ACCOUNT:
+ case GLOBAL_ACCOUNT:
+ query.append("accountPolicy");
+ break;
+
+ case PASSWORD:
+ case GLOBAL_PASSWORD:
+ query.append("passwordPolicy");
+ break;
+
+ case SYNC:
+ case GLOBAL_SYNC:
+ query.append("syncPolicy");
+ break;
+
+ default:
+ break;
+ }
+ return query;
+ }
+
+ @Override
+ public List<ExternalResource> findByPolicy(final Policy policy) {
+ TypedQuery<ExternalResource> query = entityManager.createQuery(
+ getByPolicyQuery(policy.getType()).append(" = :policy").toString(), ExternalResource.class);
+ query.setParameter("policy", policy);
+ return query.getResultList();
+ }
+
+ @Override
+ public List<ExternalResource> findWithoutPolicy(final PolicyType type) {
+ TypedQuery<ExternalResource> query = entityManager.createQuery(
+ getByPolicyQuery(type).append(" IS NULL").toString(), ExternalResource.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public List<ExternalResource> findAll() {
+ TypedQuery<ExternalResource> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e", ExternalResource.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public List<ExternalResource> findAllByPriority() {
+ TypedQuery<ExternalResource> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAExternalResource.class.getSimpleName() + " e ORDER BY e.propagationPriority",
+ ExternalResource.class);
+ return query.getResultList();
+ }
+
+ /**
+ * This method has an explicit Transactional annotation because it is called by SyncJob.
+ *
+ * @see org.apache.syncope.core.sync.impl.SyncJob
+ *
+ * @param resource entity to be merged
+ * @return the same entity, updated
+ */
+ @Override
+ @Transactional(rollbackFor = { Throwable.class })
+ public ExternalResource save(final ExternalResource resource) {
+ ExternalResource merged = entityManager.merge(resource);
+ try {
+ connRegistry.registerConnector(merged);
+ } catch (NotFoundException e) {
+ LOG.error("While registering connector for resource", e);
+ }
+ return merged;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends MappingItem> void deleteMapping(
+ final String intAttrName, final IntMappingType intMappingType, final Class<T> reference) {
+
+ if (IntMappingType.getEmbedded().contains(intMappingType)) {
+ return;
+ }
+
+ Class<? extends AbstractMappingItem> jpaRef = reference.equals(UMappingItem.class)
+ ? JPAUMappingItem.class
+ : JPARMappingItem.class;
+
+ TypedQuery<T> query = entityManager.createQuery("SELECT m FROM " + jpaRef.getSimpleName()
+ + " m WHERE m.intAttrName=:intAttrName AND m.intMappingType=:intMappingType", reference);
+ query.setParameter("intAttrName", intAttrName);
+ query.setParameter("intMappingType", intMappingType);
+
+ Set<Long> itemIds = new HashSet<>();
+ for (T item : query.getResultList()) {
+ itemIds.add(item.getKey());
+ }
+ Class<?> mappingRef = null;
+ for (Long itemId : itemIds) {
+ T item = (T) entityManager.find(jpaRef, itemId);
+ if (item != null) {
+ mappingRef = item.getMapping().getClass();
+
+ ((Mapping<T>) item.getMapping()).removeItem(item);
+ item.setMapping(null);
+
+ entityManager.remove(item);
+ }
+ }
+
+ // Make empty query cache for *MappingItem and related *Mapping
+ entityManager.getEntityManagerFactory().getCache().evict(jpaRef);
+ if (mappingRef != null) {
+ entityManager.getEntityManagerFactory().getCache().evict(mappingRef);
+ }
+ }
+
+ @Override
+ public void delete(final String name) {
+ ExternalResource resource = find(name);
+ if (resource == null) {
+ return;
+ }
+
+ taskDAO.deleteAll(resource, TaskType.PROPAGATION);
+ taskDAO.deleteAll(resource, TaskType.SYNCHRONIZATION);
+ taskDAO.deleteAll(resource, TaskType.PUSH);
+
+ for (User user : userDAO.findByResource(resource)) {
+ user.removeResource(resource);
+ }
+ for (Role role : roleDAO.findByResource(resource)) {
+ role.removeResource(resource);
+ }
+ for (AccountPolicy policy : policyDAO.findByResource(resource)) {
+ policy.removeResource(resource);
+ }
+
+ if (resource.getConnector() != null && resource.getConnector().getResources() != null
+ && !resource.getConnector().getResources().isEmpty()) {
+
+ resource.getConnector().getResources().remove(resource);
+ }
+ 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.getRmapping() != null) {
+ for (MappingItem item : resource.getRmapping().getItems()) {
+ item.setMapping(null);
+ }
+ resource.getRmapping().getItems().clear();
+ resource.getRmapping().setResource(null);
+ resource.setRmapping(null);
+ }
+
+ entityManager.remove(resource);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
new file mode 100644
index 0000000..327149f
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPALoggerDAO.java
@@ -0,0 +1,69 @@
+/*
+ * 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.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.core.persistence.api.dao.LoggerDAO;
+import org.apache.syncope.core.persistence.api.entity.Logger;
+import org.apache.syncope.core.persistence.jpa.entity.JPALogger;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPALoggerDAO extends AbstractDAO<Logger, String> implements LoggerDAO {
+
+ @Override
+ public Logger find(final String key) {
+ return entityManager.find(JPALogger.class, key);
+ }
+
+ @Override
+ public List<Logger> findAll(final LoggerType type) {
+ TypedQuery<Logger> query = entityManager.createQuery(
+ "SELECT e FROM " + JPALogger.class.getSimpleName() + " e WHERE e.type=:type", Logger.class);
+ query.setParameter("type", type);
+ return query.getResultList();
+ }
+
+ @Override
+ public Logger save(final Logger logger) {
+ // Audit loggers must be either OFF or DEBUG, no more options
+ if (LoggerType.AUDIT == logger.getType() && LoggerLevel.OFF != logger.getLevel()) {
+ logger.setLevel(LoggerLevel.DEBUG);
+ }
+ return entityManager.merge(logger);
+ }
+
+ @Override
+ public void delete(final Logger logger) {
+ entityManager.remove(logger);
+ }
+
+ @Override
+ public void delete(final String key) {
+ Logger logger = find(key);
+ if (logger == null) {
+ return;
+ }
+
+ delete(logger);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
new file mode 100644
index 0000000..8be8c72
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAMembershipDAO.java
@@ -0,0 +1,103 @@
+/*
+ * 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.NoResultException;
+import javax.persistence.Query;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.MembershipDAO;
+import org.apache.syncope.core.persistence.api.dao.NotFoundException;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.membership.Membership;
+import org.apache.syncope.core.persistence.api.entity.role.Role;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMembership;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAMembershipDAO extends AbstractDAO<Membership, Long> implements MembershipDAO {
+
+ @Autowired
+ private UserDAO userDAO;
+
+ @Override
+ public Membership find(final Long key) {
+ return entityManager.find(JPAMembership.class, key);
+ }
+
+ @Override
+ public Membership find(final User user, final Role role) {
+ Query query = entityManager.createQuery(
+ "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e WHERE e.user = :user AND e.role = :role");
+ query.setParameter("user", user);
+ query.setParameter("role", role);
+
+ Membership result = null;
+
+ try {
+ result = (Membership) query.getSingleResult();
+ } catch (NoResultException e) {
+ LOG.debug("No membership was found for user {} and role {}", user, role, e);
+ }
+
+ return result;
+ }
+
+ @Override
+ public List<Membership> findAll() {
+ TypedQuery<Membership> query = entityManager.createQuery(
+ "SELECT e FROM " + JPAMembership.class.getSimpleName() + " e", Membership.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public Membership save(final Membership membership) {
+ return entityManager.merge(membership);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ Membership membership = find(key);
+ if (membership == null) {
+ return;
+ }
+
+ membership.getUser().removeMembership(membership);
+ userDAO.save(membership.getUser());
+
+ entityManager.remove(membership);
+ }
+
+ @Override
+ public Membership authFetch(final Long key) {
+ if (key == null) {
+ throw new NotFoundException("Null membership key");
+ }
+
+ Membership membership = find(key);
+ if (membership == null) {
+ throw new NotFoundException("Membership " + key);
+ }
+
+ return membership;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
new file mode 100644
index 0000000..54ae649
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPANotificationDAO.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import java.util.List;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.core.persistence.api.dao.NotificationDAO;
+import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidEntityException;
+import org.apache.syncope.core.persistence.api.entity.Notification;
+import org.apache.syncope.core.persistence.jpa.entity.JPANotification;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPANotificationDAO extends AbstractDAO<Notification, Long> implements NotificationDAO {
+
+ @Override
+ public Notification find(final Long key) {
+ return entityManager.find(JPANotification.class, key);
+ }
+
+ @Override
+ public List<Notification> findAll() {
+ TypedQuery<Notification> query = entityManager.createQuery(
+ "SELECT e FROM " + JPANotification.class.getSimpleName() + " e", Notification.class);
+ return query.getResultList();
+ }
+
+ @Override
+ public Notification save(final Notification notification) throws InvalidEntityException {
+ return entityManager.merge(notification);
+ }
+
+ @Override
+ public void delete(final Long key) {
+ entityManager.remove(find(key));
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
new file mode 100644
index 0000000..9e2f757
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrDAO.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.syncope.core.persistence.jpa.dao;
+
+import org.apache.syncope.core.persistence.api.dao.PlainAttrDAO;
+import org.apache.syncope.core.persistence.api.entity.Attributable;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttr;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttr;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPlainAttrDAO extends AbstractDAO<PlainAttr, Long> implements PlainAttrDAO {
+
+ public <T extends PlainAttr> Class<? extends AbstractPlainAttr> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return CPlainAttr.class.isAssignableFrom(reference)
+ ? JPACPlainAttr.class
+ : RPlainAttr.class.isAssignableFrom(reference)
+ ? JPARPlainAttr.class
+ : MPlainAttr.class.isAssignableFrom(reference)
+ ? JPAMPlainAttr.class
+ : UPlainAttr.class.isAssignableFrom(reference)
+ ? JPAUPlainAttr.class
+ : null;
+ }
+
+ @Override
+ public <T extends PlainAttr> T find(final Long key, final Class<T> reference) {
+ return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ }
+
+ @Override
+ public <T extends PlainAttr> void delete(final Long key, final Class<T> reference) {
+ T attribute = find(key, reference);
+ if (attribute == null) {
+ return;
+ }
+
+ delete(attribute);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public <T extends PlainAttr> void delete(final T plainAttr) {
+ if (plainAttr.getOwner() != null) {
+ ((Attributable<T, ?, ?>) plainAttr.getOwner()).removePlainAttr(plainAttr);
+ }
+
+ entityManager.remove(plainAttr);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
new file mode 100644
index 0000000..17861d6
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainAttrValueDAO.java
@@ -0,0 +1,104 @@
+/*
+ * 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.PlainAttrValueDAO;
+import org.apache.syncope.core.persistence.api.entity.PlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.role.RPlainAttrValue;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainAttrValue;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrUniqueValue;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainAttrValue;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPlainAttrValueDAO extends AbstractDAO<PlainAttrValue, Long> implements PlainAttrValueDAO {
+
+ private <T extends PlainAttrValue> Class<? extends AbstractPlainAttrValue> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return reference.equals(CPlainAttrValue.class)
+ ? JPACPlainAttrValue.class
+ : reference.equals(CPlainAttrUniqueValue.class)
+ ? JPACPlainAttrUniqueValue.class
+ : reference.equals(RPlainAttrValue.class)
+ ? JPARPlainAttrValue.class
+ : reference.equals(RPlainAttrUniqueValue.class)
+ ? JPARPlainAttrUniqueValue.class
+ : reference.equals(MPlainAttrValue.class)
+ ? JPAMPlainAttrValue.class
+ : reference.equals(MPlainAttrUniqueValue.class)
+ ? JPAMPlainAttrUniqueValue.class
+ : reference.equals(UPlainAttrValue.class)
+ ? JPAUPlainAttrValue.class
+ : reference.equals(UPlainAttrUniqueValue.class)
+ ? JPAUPlainAttrUniqueValue.class
+ : null;
+ }
+
+ @Override
+ public <T extends PlainAttrValue> T find(final Long key, final Class<T> reference) {
+ return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ }
+
+ @Override
+ public <T extends PlainAttrValue> 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 PlainAttrValue> T save(final T attributeValue) {
+ return entityManager.merge(attributeValue);
+ }
+
+ @Override
+ public <T extends PlainAttrValue> void delete(final Long id, final Class<T> reference) {
+ T attributeValue = find(id, reference);
+ if (attributeValue == null) {
+ return;
+ }
+
+ delete(attributeValue);
+ }
+
+ @Override
+ public <T extends PlainAttrValue> void delete(final T attrValue) {
+ if (attrValue.getAttr() != null) {
+ attrValue.getAttr().removeValue(attrValue);
+ }
+
+ entityManager.remove(attrValue);
+ }
+}
http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
----------------------------------------------------------------------
diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
new file mode 100644
index 0000000..9546557
--- /dev/null
+++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAPlainSchemaDAO.java
@@ -0,0 +1,141 @@
+/*
+ * 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.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.persistence.TypedQuery;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.core.persistence.api.dao.AttrTemplateDAO;
+import org.apache.syncope.core.persistence.api.dao.ExternalResourceDAO;
+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.AttributableUtil;
+import org.apache.syncope.core.persistence.api.entity.PlainAttr;
+import org.apache.syncope.core.persistence.api.entity.PlainSchema;
+import org.apache.syncope.core.persistence.api.entity.conf.CPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.membership.MPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.role.RMappingItem;
+import org.apache.syncope.core.persistence.api.entity.role.RPlainAttr;
+import org.apache.syncope.core.persistence.api.entity.role.RPlainSchema;
+import org.apache.syncope.core.persistence.api.entity.user.UMappingItem;
+import org.apache.syncope.core.persistence.api.entity.user.UPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.AbstractPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.conf.JPACPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.role.JPARPlainSchema;
+import org.apache.syncope.core.persistence.jpa.entity.user.JPAUPlainSchema;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public class JPAPlainSchemaDAO extends AbstractDAO<PlainSchema, String> implements PlainSchemaDAO {
+
+ @Autowired
+ private PlainAttrDAO attrDAO;
+
+ @Autowired
+ private AttrTemplateDAO<PlainSchema> attrTemplateDAO;
+
+ @Autowired
+ private ExternalResourceDAO resourceDAO;
+
+ private <T extends PlainSchema> Class<? extends AbstractPlainSchema> getJPAEntityReference(
+ final Class<T> reference) {
+
+ return CPlainSchema.class.isAssignableFrom(reference)
+ ? JPACPlainSchema.class
+ : RPlainSchema.class.isAssignableFrom(reference)
+ ? JPARPlainSchema.class
+ : MPlainSchema.class.isAssignableFrom(reference)
+ ? JPAMPlainSchema.class
+ : UPlainSchema.class.isAssignableFrom(reference)
+ ? JPAUPlainSchema.class
+ : null;
+ }
+
+ @Override
+ public <T extends PlainSchema> T find(final String key, final Class<T> reference) {
+ return reference.cast(entityManager.find(getJPAEntityReference(reference), key));
+ }
+
+ @Override
+ public <T extends PlainSchema> 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 PlainAttr> List<T> findAttrs(final PlainSchema schema, final Class<T> reference) {
+ final StringBuilder queryString = new StringBuilder("SELECT e FROM ").
+ append(((JPAPlainAttrDAO) attrDAO).getJPAEntityReference(reference).getSimpleName()).
+ append(" e WHERE e.");
+ if (RPlainAttr.class.isAssignableFrom(reference) || MPlainAttr.class.isAssignableFrom(reference)) {
+ queryString.append("template.");
+ }
+ queryString.append("schema=:schema");
+
+ TypedQuery<T> query = entityManager.createQuery(queryString.toString(), reference);
+ query.setParameter("schema", schema);
+
+ return query.getResultList();
+ }
+
+ @Override
+ public <T extends PlainSchema> T save(final T schema) {
+ return entityManager.merge(schema);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void delete(final String key, final AttributableUtil attributableUtil) {
+ PlainSchema schema = find(key, attributableUtil.plainSchemaClass());
+ if (schema == null) {
+ return;
+ }
+
+ final Set<Long> attrIds = new HashSet<>();
+ for (PlainAttr attr : findAttrs(schema, attributableUtil.plainAttrClass())) {
+ attrIds.add(attr.getKey());
+ }
+ for (Long attrId : attrIds) {
+ attrDAO.delete(attrId, attributableUtil.plainAttrClass());
+ }
+
+ if (attributableUtil.getType() == AttributableType.ROLE
+ || attributableUtil.getType() == AttributableType.MEMBERSHIP) {
+
+ for (Iterator<Number> it = attrTemplateDAO.
+ findBySchemaName(schema.getKey(), attributableUtil.plainAttrTemplateClass()).iterator();
+ it.hasNext();) {
+
+ attrTemplateDAO.delete(it.next().longValue(), attributableUtil.plainAttrTemplateClass());
+ }
+ }
+
+ resourceDAO.deleteMapping(key, attributableUtil.intMappingType(), UMappingItem.class);
+ resourceDAO.deleteMapping(key, attributableUtil.intMappingType(), RMappingItem.class);
+
+ entityManager.remove(schema);
+ }
+}