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); + } +}
