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/JPAUserDAO.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java new file mode 100644 index 0000000..c08e1a2 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAUserDAO.java @@ -0,0 +1,287 @@ +/* + * 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 java.util.Set; +import javax.annotation.Resource; +import javax.persistence.NoResultException; +import javax.persistence.TypedQuery; +import org.apache.syncope.common.lib.types.AttributableType; +import org.apache.syncope.common.lib.types.SubjectType; +import org.apache.syncope.core.persistence.api.RoleEntitlementUtil; +import org.apache.syncope.core.persistence.api.dao.NotFoundException; +import org.apache.syncope.core.persistence.api.dao.RoleDAO; +import org.apache.syncope.core.persistence.api.dao.SubjectSearchDAO; +import org.apache.syncope.core.persistence.api.dao.UserDAO; +import org.apache.syncope.core.persistence.api.dao.search.AttributeCond; +import org.apache.syncope.core.persistence.api.dao.search.OrderByClause; +import org.apache.syncope.core.persistence.api.dao.search.SearchCond; +import org.apache.syncope.core.persistence.api.dao.search.SubjectCond; +import org.apache.syncope.core.persistence.api.entity.AttributableUtilFactory; +import org.apache.syncope.core.persistence.api.entity.ExternalResource; +import org.apache.syncope.core.persistence.api.entity.Subject; +import org.apache.syncope.core.persistence.api.entity.VirAttr; +import org.apache.syncope.core.persistence.api.entity.membership.Membership; +import org.apache.syncope.core.persistence.api.entity.user.SecurityQuestion; +import org.apache.syncope.core.persistence.api.entity.user.UDerAttr; +import org.apache.syncope.core.persistence.api.entity.user.UPlainAttr; +import org.apache.syncope.core.persistence.api.entity.user.UPlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.user.UVirAttr; +import org.apache.syncope.core.persistence.api.entity.user.User; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUser; +import org.apache.syncope.core.misc.security.AuthContextUtil; +import org.apache.syncope.core.misc.security.UnauthorizedRoleException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +@Repository +public class JPAUserDAO extends AbstractSubjectDAO<UPlainAttr, UDerAttr, UVirAttr> implements UserDAO { + + @Autowired + private SubjectSearchDAO searchDAO; + + @Autowired + private RoleDAO roleDAO; + + @Resource(name = "anonymousUser") + private String anonymousUser; + + @Autowired + private AttributableUtilFactory attrUtilFactory; + + @Override + protected Subject<UPlainAttr, UDerAttr, UVirAttr> findInternal(Long key) { + return find(key); + } + + @Override + public User find(final Long key) { + TypedQuery<User> query = entityManager.createQuery( + "SELECT e FROM " + JPAUser.class.getSimpleName() + " e WHERE e.id = :id", User.class); + query.setParameter("id", key); + + User result = null; + try { + result = query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("No user found with id {}", key, e); + } + + return result; + } + + @Override + public User find(final String username) { + TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName() + + " e WHERE e.username = :username", User.class); + query.setParameter("username", username); + + User result = null; + try { + result = query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("No user found with username {}", username, e); + } + + return result; + } + + @Override + public User findByWorkflowId(final String workflowId) { + TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName() + + " e WHERE e.workflowId = :workflowId", User.class); + query.setParameter("workflowId", workflowId); + + User result = null; + try { + result = query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("No user found with workflow id {}", workflowId, e); + } + + return result; + } + + @Override + public User findByToken(final String token) { + TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName() + + " e WHERE e.token LIKE :token", User.class); + query.setParameter("token", token); + + User result = null; + try { + result = query.getSingleResult(); + } catch (NoResultException e) { + LOG.debug("No user found with token {}", token, e); + } + + return result; + } + + @Override + public List<User> findBySecurityQuestion(final SecurityQuestion securityQuestion) { + TypedQuery<User> query = entityManager.createQuery("SELECT e FROM " + JPAUser.class.getSimpleName() + + " e WHERE e.securityQuestion = :securityQuestion", User.class); + query.setParameter("securityQuestion", securityQuestion); + + return query.getResultList(); + } + + @SuppressWarnings("unchecked") + @Override + public List<User> findByAttrValue(final String schemaName, final UPlainAttrValue attrValue) { + return (List<User>) findByAttrValue( + schemaName, attrValue, attrUtilFactory.getInstance(AttributableType.USER)); + } + + @SuppressWarnings("unchecked") + @Override + public User findByAttrUniqueValue(final String schemaName, final UPlainAttrValue attrUniqueValue) { + return (User) findByAttrUniqueValue(schemaName, attrUniqueValue, + attrUtilFactory.getInstance(AttributableType.USER)); + } + + @SuppressWarnings("unchecked") + @Override + public List<User> findByDerAttrValue(final String schemaName, final String value) { + return (List<User>) findByDerAttrValue( + schemaName, value, attrUtilFactory.getInstance(AttributableType.USER)); + } + + @SuppressWarnings("unchecked") + @Override + public List<User> findByResource(final ExternalResource resource) { + return (List<User>) findByResource(resource, attrUtilFactory.getInstance(AttributableType.USER)); + } + + @Override + public final List<User> findAll(final Set<Long> adminRoles, final int page, final int itemsPerPage) { + return findAll(adminRoles, page, itemsPerPage, Collections.<OrderByClause>emptyList()); + } + + private SearchCond getAllMatchingCond() { + SubjectCond idCond = new SubjectCond(AttributeCond.Type.ISNOTNULL); + idCond.setSchema("id"); + return SearchCond.getLeafCond(idCond); + } + + @Override + public List<User> findAll(final Set<Long> adminRoles, + final int page, final int itemsPerPage, final List<OrderByClause> orderBy) { + + return searchDAO.search( + adminRoles, getAllMatchingCond(), page, itemsPerPage, orderBy, SubjectType.USER); + } + + @Override + public final int count(final Set<Long> adminRoles) { + return searchDAO.count(adminRoles, getAllMatchingCond(), SubjectType.USER); + } + + @Override + public User save(final User user) { + final User merged = entityManager.merge(user); + for (VirAttr virAttr : merged.getVirAttrs()) { + virAttr.getValues().clear(); + virAttr.getValues().addAll(user.getVirAttr(virAttr.getSchema().getKey()).getValues()); + } + + return merged; + } + + @Override + public void delete(final Long key) { + User user = (User) findInternal(key); + if (user == null) { + return; + } + + delete(user); + } + + @Override + public void delete(final User user) { + // Not calling membershipDAO.delete() here because it would try to save this user as well, thus going into + // ConcurrentModificationException + for (Membership membership : user.getMemberships()) { + membership.setUser(null); + + roleDAO.save(membership.getRole()); + membership.setRole(null); + + entityManager.remove(membership); + } + user.getMemberships().clear(); + + entityManager.remove(user); + } + + private void securityChecks(final User user) { + // Allows anonymous (during self-registration) and self (during self-update) to read own user, + // otherwise goes thorugh security checks to see if needed role entitlements are owned + if (!AuthContextUtil.getAuthenticatedUsername().equals(anonymousUser) + && !AuthContextUtil.getAuthenticatedUsername().equals(user.getUsername())) { + + Set<Long> roleKeys = user.getRoleKeys(); + Set<Long> adminRoleKeys = RoleEntitlementUtil.getRoleKeys(AuthContextUtil.getOwnedEntitlementNames()); + roleKeys.removeAll(adminRoleKeys); + if (!roleKeys.isEmpty()) { + throw new UnauthorizedRoleException(roleKeys); + } + } + } + + @Transactional(readOnly = true) + @Override + public User authFetch(final Long key) { + if (key == null) { + throw new NotFoundException("Null user id"); + } + + User user = find(key); + if (user == null) { + throw new NotFoundException("User " + key); + } + + securityChecks(user); + + return user; + } + + @Transactional(readOnly = true) + @Override + public User authFetch(final String username) { + if (username == null) { + throw new NotFoundException("Null username"); + } + + User user = find(username); + if (user == null) { + throw new NotFoundException("User " + username); + } + + securityChecks(user); + + return user; + } + +}
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/JPAVirAttrDAO.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.java new file mode 100644 index 0000000..2235295 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirAttrDAO.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.VirAttrDAO; +import org.apache.syncope.core.persistence.api.entity.Attributable; +import org.apache.syncope.core.persistence.api.entity.VirAttr; +import org.apache.syncope.core.persistence.api.entity.membership.MVirAttr; +import org.apache.syncope.core.persistence.api.entity.role.RVirAttr; +import org.apache.syncope.core.persistence.api.entity.user.UVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.AbstractVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.role.JPARVirAttr; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirAttr; +import org.springframework.stereotype.Repository; + +@Repository +public class JPAVirAttrDAO extends AbstractDAO<VirAttr, Long> implements VirAttrDAO { + + public <T extends VirAttr> Class<? extends AbstractVirAttr> getJPAEntityReference( + final Class<T> reference) { + + return RVirAttr.class.isAssignableFrom(reference) + ? JPARVirAttr.class + : MVirAttr.class.isAssignableFrom(reference) + ? JPAMVirAttr.class + : UVirAttr.class.isAssignableFrom(reference) + ? JPAUVirAttr.class + : null; + } + + @Override + public <T extends VirAttr> T find(final Long key, final Class<T> reference) { + return reference.cast(entityManager.find(getJPAEntityReference(reference), key)); + } + + @Override + public <T extends VirAttr> 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 VirAttr> T save(final T virAttr) { + return entityManager.merge(virAttr); + } + + @Override + public <T extends VirAttr> void delete(final Long key, final Class<T> reference) { + T virAttr = find(key, reference); + if (virAttr == null) { + return; + } + + delete(virAttr); + } + + @Override + @SuppressWarnings("unchecked") + public <T extends VirAttr> void delete(final T virAttr) { + if (virAttr.getOwner() != null) { + ((Attributable<?, ?, T>) virAttr.getOwner()).removeVirAttr(virAttr); + } + + entityManager.remove(virAttr); + } +} 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/JPAVirSchemaDAO.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java new file mode 100644 index 0000000..f7a1e55 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/JPAVirSchemaDAO.java @@ -0,0 +1,131 @@ +/* + * 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.VirAttrDAO; +import org.apache.syncope.core.persistence.api.dao.VirSchemaDAO; +import org.apache.syncope.core.persistence.api.entity.AttributableUtil; +import org.apache.syncope.core.persistence.api.entity.VirAttr; +import org.apache.syncope.core.persistence.api.entity.VirSchema; +import org.apache.syncope.core.persistence.api.entity.membership.MVirSchema; +import org.apache.syncope.core.persistence.api.entity.role.RVirSchema; +import org.apache.syncope.core.persistence.api.entity.user.UMappingItem; +import org.apache.syncope.core.persistence.api.entity.user.UVirAttr; +import org.apache.syncope.core.persistence.api.entity.user.UVirSchema; +import org.apache.syncope.core.persistence.jpa.entity.AbstractVirSchema; +import org.apache.syncope.core.persistence.jpa.entity.membership.JPAMVirSchema; +import org.apache.syncope.core.persistence.jpa.entity.role.JPARVirSchema; +import org.apache.syncope.core.persistence.jpa.entity.user.JPAUVirSchema; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class JPAVirSchemaDAO extends AbstractDAO<VirSchema, String> implements VirSchemaDAO { + + @Autowired + private VirAttrDAO virAttrDAO; + + @Autowired + private AttrTemplateDAO<VirSchema> attrTemplateDAO; + + @Autowired + private ExternalResourceDAO resourceDAO; + + private <T extends VirSchema> Class<? extends AbstractVirSchema> getJPAEntityReference(final Class<T> reference) { + return RVirSchema.class.isAssignableFrom(reference) + ? JPARVirSchema.class + : MVirSchema.class.isAssignableFrom(reference) + ? JPAMVirSchema.class + : UVirSchema.class.isAssignableFrom(reference) + ? JPAUVirSchema.class + : null; + } + + @Override + public <T extends VirSchema> T find(final String key, final Class<T> reference) { + return reference.cast(entityManager.find(getJPAEntityReference(reference), key)); + } + + @Override + public <T extends VirSchema> 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 VirAttr> List<T> findAttrs(final VirSchema schema, final Class<T> reference) { + final StringBuilder queryString = new StringBuilder("SELECT e FROM "). + append(((JPAVirAttrDAO) virAttrDAO).getJPAEntityReference(reference).getSimpleName()). + append(" e WHERE e."); + if (UVirAttr.class.isAssignableFrom(reference)) { + queryString.append("virSchema"); + } 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 VirSchema> T save(final T virSchema) { + return entityManager.merge(virSchema); + } + + @Override + public void delete(final String name, final AttributableUtil attributableUtil) { + final VirSchema schema = find(name, attributableUtil.virSchemaClass()); + if (schema == null) { + return; + } + + final Set<Long> attrIds = new HashSet<>(); + for (VirAttr attr : findAttrs(schema, attributableUtil.virAttrClass())) { + attrIds.add(attr.getKey()); + } + for (Long attrId : attrIds) { + virAttrDAO.delete(attrId, attributableUtil.virAttrClass()); + } + + if (attributableUtil.getType() != AttributableType.USER) { + for (Iterator<Number> it = attrTemplateDAO. + findBySchemaName(schema.getKey(), attributableUtil.virAttrTemplateClass()).iterator(); + it.hasNext();) { + + attrTemplateDAO.delete(it.next().longValue(), attributableUtil.virAttrTemplateClass()); + } + } + + resourceDAO.deleteMapping(name, attributableUtil.virIntMappingType(), 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/OrderBySupport.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java new file mode 100644 index 0000000..63f442e --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/OrderBySupport.java @@ -0,0 +1,47 @@ +/* + * 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.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class OrderBySupport { + + static class Item { + + protected String select; + + protected String where; + + protected String orderBy; + + protected boolean isEmpty() { + return (select == null || select.isEmpty()) + && (where == null || where.isEmpty()) + && (orderBy == null || orderBy.isEmpty()); + } + } + + protected Set<SearchSupport.SearchView> views = new HashSet<>(); + + protected List<Item> items = new ArrayList<>(); + +} 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/SearchSupport.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.java new file mode 100644 index 0000000..6922b85 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/dao/SearchSupport.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 org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.common.lib.types.SubjectType; + +class SearchSupport { + + static class SearchView { + + protected String alias; + + protected String name; + + protected SearchView(final String alias, final String name) { + this.alias = alias; + this.name = name; + } + + @Override + public boolean equals(final Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + } + + private final SubjectType type; + + public SearchSupport(final SubjectType type) { + this.type = type; + } + + public String fieldName(final AttrSchemaType type) { + String result; + + switch (type) { + case Boolean: + result = "booleanvalue"; + break; + + case Date: + result = "datevalue"; + break; + + case Double: + result = "doublevalue"; + break; + + case Long: + result = "longvalue"; + break; + + case String: + case Enum: + result = "stringvalue"; + break; + + default: + result = null; + } + + return result; + } + + public SearchView field() { + String result = ""; + + switch (type) { + case USER: + default: + result = "user_search"; + break; + + case ROLE: + result = "role_search"; + break; + } + + return new SearchView("sv", result); + } + + public SearchView attr() { + return new SearchView("sva", field().name + "_attr"); + } + + public SearchView membership() { + return new SearchView("svm", field().name + "_membership"); + } + + public SearchView nullAttr() { + return new SearchView("svna", field().name + "_null_attr"); + } + + public SearchView resource() { + return new SearchView("svr", field().name + "_resource"); + } + + public SearchView roleResource() { + return new SearchView("svrr", field().name + "_role_resource"); + } + + public SearchView uniqueAttr() { + return new SearchView("svua", field().name + "_unique_attr"); + } + + public SearchView entitlements() { + return new SearchView("sve", field().name + "_entitlements"); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnnotatedEntity.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnnotatedEntity.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnnotatedEntity.java new file mode 100644 index 0000000..c9bbe77 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAnnotatedEntity.java @@ -0,0 +1,113 @@ +/* + * 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.entity; + +import java.util.Date; +import javax.persistence.Column; +import javax.persistence.EntityListeners; +import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import org.apache.syncope.core.persistence.api.entity.AnnotatedEntity; + +/** + * Abstract wrapper for common system information. + */ +@MappedSuperclass +@EntityListeners(value = AnnotatedEntityListener.class) +public abstract class AbstractAnnotatedEntity<KEY> extends AbstractEntity<KEY> implements AnnotatedEntity<KEY> { + + private static final long serialVersionUID = -4801685541488201219L; + + /** + * Username of the user that has created this profile. + * <br/> + * Reference to existing user cannot be used: the creator can either be <tt>admin</tt> or was deleted. + */ + @Column(nullable = false) + private String creator; + + /** + * Creation date. + */ + @Column(nullable = false) + @Temporal(TemporalType.TIMESTAMP) + private Date creationDate; + + /** + * Username of the user that has performed the last modification to this profile. + * <br/> + * This field cannot be null: at creation time it needs to be initialized with the creator username. + * <br/> + * The modifier can be the user itself if the last performed change was a self-modification. + * <br/> + * Reference to existing user cannot be used: the creator can either be <tt>admin</tt> or was deleted. + */ + @Column(nullable = false) + private String lastModifier; + + /** + * Last change date. + * <br/> + * This field cannot be null: at creation time it needs to be initialized with <tt>creationDate</tt> field value. + */ + @Column(nullable = false) + @Temporal(TemporalType.TIMESTAMP) + private Date lastChangeDate; + + @Override + public String getCreator() { + return creator; + } + + @Override + public void setCreator(final String creator) { + this.creator = creator; + } + + @Override + public Date getCreationDate() { + return creationDate == null ? null : new Date(creationDate.getTime()); + } + + @Override + public void setCreationDate(final Date creationDate) { + this.creationDate = creationDate == null ? null : new Date(creationDate.getTime()); + } + + @Override + public String getLastModifier() { + return lastModifier; + } + + @Override + public void setLastModifier(final String lastModifier) { + this.lastModifier = lastModifier; + } + + @Override + public Date getLastChangeDate() { + return lastChangeDate == null ? creationDate : lastChangeDate; + } + + @Override + public void setLastChangeDate(final Date lastChangeDate) { + this.lastChangeDate = lastChangeDate == null ? null : new Date(lastChangeDate.getTime()); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java new file mode 100644 index 0000000..f2a32a1 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttrTemplate.java @@ -0,0 +1,28 @@ +/* + * 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.entity; + +import org.apache.syncope.core.persistence.api.entity.AttrTemplate; +import org.apache.syncope.core.persistence.api.entity.Schema; + +public abstract class AbstractAttrTemplate<S extends Schema> extends AbstractEntity<Long> implements AttrTemplate<S> { + + private static final long serialVersionUID = 4829112252713766666L; + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java new file mode 100644 index 0000000..d648748 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractAttributable.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.entity; + +import java.util.HashMap; +import java.util.Map; +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.DerSchema; +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.VirAttr; +import org.apache.syncope.core.persistence.api.entity.VirSchema; + +public abstract class AbstractAttributable<P extends PlainAttr, D extends DerAttr, V extends VirAttr> + extends AbstractAnnotatedEntity<Long> implements Attributable<P, D, V> { + + private static final long serialVersionUID = -4801685541488201119L; + + @Override + public P getPlainAttr(final String plainSchemaName) { + P result = null; + for (P plainAttr : getPlainAttrs()) { + if (plainAttr != null && plainAttr.getSchema() != null + && plainSchemaName.equals(plainAttr.getSchema().getKey())) { + + result = plainAttr; + } + } + return result; + } + + @Override + public D getDerAttr(final String derSchemaName) { + D result = null; + for (D derAttr : getDerAttrs()) { + if (derAttr != null && derAttr.getSchema() != null + && derSchemaName.equals(derAttr.getSchema().getKey())) { + + result = derAttr; + } + } + + return result; + } + + @Override + public V getVirAttr(final String virSchemaName) { + V result = null; + for (V virAttr : getVirAttrs()) { + if (virAttr != null && virAttr.getSchema() != null + && virSchemaName.equals(virAttr.getSchema().getKey())) { + + result = virAttr; + } + } + + return result; + } + + protected Map<PlainSchema, P> getPlainAttrMap() { + final Map<PlainSchema, P> map = new HashMap<>(); + + for (P attr : getPlainAttrs()) { + map.put(attr.getSchema(), attr); + } + + return map; + } + + protected Map<DerSchema, D> getDerAttrMap() { + final Map<DerSchema, D> map = new HashMap<>(); + + for (D attr : getDerAttrs()) { + map.put(attr.getSchema(), attr); + } + + return map; + } + + protected Map<VirSchema, V> getVirAttrMap() { + final Map<VirSchema, V> map = new HashMap<>(); + + for (V attr : getVirAttrs()) { + map.put(attr.getSchema(), attr); + } + + return map; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java new file mode 100644 index 0000000..c43e786 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttr.java @@ -0,0 +1,52 @@ +/* + * 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.entity; + +import java.util.Collection; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import org.apache.syncope.core.persistence.api.entity.DerAttr; +import org.apache.syncope.core.persistence.api.entity.PlainAttr; +import org.apache.syncope.core.misc.jexl.JexlUtil; + +@MappedSuperclass +public abstract class AbstractDerAttr extends AbstractEntity<Long> implements DerAttr { + + private static final long serialVersionUID = 4740924251090424771L; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + protected Long id; + + @Override + public Long getKey() { + return id; + } + + /** + * @param attributes the set of attributes against which evaluate this derived attribute + * @return the value of this derived attribute + */ + @Override + public String getValue(final Collection<? extends PlainAttr> attributes) { + return JexlUtil.evaluate(getSchema().getExpression(), getOwner(), attributes); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java new file mode 100644 index 0000000..3846b12 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerAttrTemplate.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.core.persistence.jpa.entity; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import org.apache.syncope.core.persistence.api.entity.DerSchema; + +@MappedSuperclass +public abstract class AbstractDerAttrTemplate<D extends DerSchema> extends AbstractAttrTemplate<D> { + + private static final long serialVersionUID = 8871895736733379865L; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + protected Long id; + + @Override + public Long getKey() { + return id; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java new file mode 100644 index 0000000..195f41d --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractDerSchema.java @@ -0,0 +1,85 @@ +/* + * 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.entity; + +import javax.persistence.Column; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; +import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.core.persistence.api.entity.DerSchema; +import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck; + +@MappedSuperclass +@SchemaNameCheck +public abstract class AbstractDerSchema extends AbstractEntity<String> implements DerSchema { + + private static final long serialVersionUID = -6173643493348674060L; + + @Id + private String name; + + @Column(nullable = false) + private String expression; + + @Override + public String getKey() { + return name; + } + + @Override + public void setKey(final String key) { + this.name = key; + } + + @Override + public String getExpression() { + return expression; + } + + @Override + public void setExpression(final String expression) { + this.expression = expression; + } + + @Override + public AttrSchemaType getType() { + return AttrSchemaType.String; + } + + @Override + public String getMandatoryCondition() { + return Boolean.FALSE.toString().toLowerCase(); + } + + @Override + public boolean isMultivalue() { + return Boolean.TRUE; + } + + @Override + public boolean isUniqueConstraint() { + return Boolean.FALSE; + } + + @Override + public boolean isReadonly() { + return Boolean.FALSE; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java new file mode 100644 index 0000000..dfd706d --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractEntity.java @@ -0,0 +1,111 @@ +/* + * 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.entity; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.syncope.core.persistence.api.entity.Entity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeanUtils; + +public abstract class AbstractEntity<KEY> implements Entity<KEY> { + + private static final long serialVersionUID = -9017214159540857901L; + + /** + * Logger. + */ + protected static final Logger LOG = LoggerFactory.getLogger(AbstractEntity.class); + + protected void checkType(final Object object, final Class<?> clazz) { + if (object != null && !clazz.isInstance(object)) { + throw new ClassCastException("Expected " + clazz.getName() + ", got " + object.getClass().getName()); + } + } + + /** + * @param property the integer representing a boolean value + * @return the boolean value corresponding to the property param + */ + public final boolean isBooleanAsInteger(final Integer property) { + return property != null && property == 1; + } + + /** + * @param value the boolean value to be represented as integer + * @return the integer corresponding to the property param + */ + public final Integer getBooleanAsInteger(final Boolean value) { + return Boolean.TRUE.equals(value) + ? 1 + : 0; + } + + /** + * @return fields to be excluded when computing equals() or hashcode() + */ + private String[] getExcludeFields() { + Set<String> excludeFields = new HashSet<>(); + + for (PropertyDescriptor propDesc : BeanUtils.getPropertyDescriptors(getClass())) { + if (propDesc.getPropertyType().isInstance(Collections.emptySet()) + || propDesc.getPropertyType().isInstance(Collections.emptyList())) { + + excludeFields.add(propDesc.getName()); + } + } + + return excludeFields.toArray(new String[] {}); + } + + @Override + public boolean equals(final Object obj) { + return EqualsBuilder.reflectionEquals(this, obj, getExcludeFields()); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this, getExcludeFields()); + } + + @Override + public String toString() { + Method method = BeanUtils.findMethod(getClass(), "getKey"); + + StringBuilder result = new StringBuilder().append(getClass().getSimpleName()).append('['); + if (method != null) { + try { + result.append(method.invoke(this)); + } catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.error("While serializing to string", e); + } + } + } + result.append(']'); + + return result.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/entity/AbstractExec.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java new file mode 100644 index 0000000..7e52010 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractExec.java @@ -0,0 +1,114 @@ +/* + * 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.entity; + +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Lob; +import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import org.apache.syncope.core.persistence.api.entity.Exec; + +@MappedSuperclass +public abstract class AbstractExec extends AbstractEntity<Long> implements Exec { + + private static final long serialVersionUID = -812344822970166317L; + + @Column(nullable = false) + protected String status; + + /** + * Any information to be accompanied to this execution's result. + */ + @Lob + protected String message; + + /** + * Start instant of this execution. + */ + @Temporal(TemporalType.TIMESTAMP) + protected Date startDate; + + /** + * End instant of this execution. + */ + @Temporal(TemporalType.TIMESTAMP) + protected Date endDate; + + @Override + public String getStatus() { + return status; + } + + @Override + public void setStatus(final String status) { + this.status = status; + } + + @Override + public String getMessage() { + return message; + } + + /** + * Set a message for this execution, taking care of replacing every null character with newline. + * + * @param message the message to set for this execution + */ + @Override + public void setMessage(String message) { + if (message != null) { + message = message.replace('\0', '\n'); + } + this.message = message; + } + + @Override + public Date getEndDate() { + return endDate == null + ? null + : new Date(endDate.getTime()); + } + + @Override + + public void setEndDate(final Date endDate) { + this.endDate = endDate == null + ? null + : new Date(endDate.getTime()); + } + + @Override + + public Date getStartDate() { + return startDate == null + ? null + : new Date(startDate.getTime()); + } + + @Override + + public void setStartDate(final Date startDate) { + this.startDate = startDate == null + ? null + : new Date(startDate.getTime()); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.java new file mode 100644 index 0000000..3a85859 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMapping.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.entity; + +import javax.persistence.Cacheable; +import javax.persistence.MappedSuperclass; +import org.apache.syncope.common.lib.types.IntMappingType; +import org.apache.syncope.core.persistence.api.entity.Mapping; +import org.apache.syncope.core.persistence.api.entity.MappingItem; + +@MappedSuperclass +@Cacheable +public abstract class AbstractMapping<T extends MappingItem> extends AbstractEntity<Long> implements Mapping<T> { + + private static final long serialVersionUID = 4316047254916259158L; + + /** + * A JEXL expression for determining how to find the account id in external resource's space. + */ + private String accountLink; + + @Override + public String getAccountLink() { + return accountLink; + } + + @Override + public void setAccountLink(final String accountLink) { + this.accountLink = accountLink; + } + + @Override + public T getAccountIdItem() { + T accountIdItem = null; + for (T item : getItems()) { + if (item.isAccountid()) { + accountIdItem = item; + } + } + return accountIdItem; + } + + protected boolean addAccountIdItem(final T accountIdItem) { + if (IntMappingType.UserVirtualSchema == accountIdItem.getIntMappingType() + || IntMappingType.RoleVirtualSchema == accountIdItem.getIntMappingType() + || IntMappingType.MembershipVirtualSchema == accountIdItem.getIntMappingType() + || IntMappingType.Password == accountIdItem.getIntMappingType()) { + + throw new IllegalArgumentException("Virtual attributes cannot be set as accountId"); + } + if (IntMappingType.Password == accountIdItem.getIntMappingType()) { + throw new IllegalArgumentException("Password attributes cannot be set as accountId"); + } + + accountIdItem.setExtAttrName(accountIdItem.getExtAttrName()); + accountIdItem.setAccountid(true); + + return this.addItem(accountIdItem); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java new file mode 100644 index 0000000..c183908 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractMappingItem.java @@ -0,0 +1,190 @@ +/* + * 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.entity; + +import javax.persistence.Basic; +import javax.persistence.Cacheable; +import javax.persistence.Column; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.MappedSuperclass; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import org.apache.syncope.common.lib.types.IntMappingType; +import org.apache.syncope.common.lib.types.MappingPurpose; +import org.apache.syncope.core.persistence.api.entity.MappingItem; + +@MappedSuperclass +@Cacheable +public abstract class AbstractMappingItem extends AbstractEntity<Long> implements MappingItem { + + private static final long serialVersionUID = 7383601853619332424L; + + @Column(nullable = true) + private String intAttrName; + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private IntMappingType intMappingType; + + /** + * Target resource's field to be mapped. + */ + @Column(nullable = true) + private String extAttrName; + + /** + * Specify if the mapped target resource's field is nullable. + */ + @Column(nullable = false) + private String mandatoryCondition; + + /** + * Specify if the mapped target resource's field is the key. + */ + @Column(nullable = false) + @Basic + @Min(0) + @Max(1) + private Integer accountid; + + /** + * Specify if the mapped target resource's field is the password. + */ + @Column(nullable = false) + @Basic + @Min(0) + @Max(1) + private Integer password; + + /** + * Mapping purposes: SYNCHRONIZATION, PROPAGATION, BOTH. + */ + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private MappingPurpose purpose; + + public AbstractMappingItem() { + super(); + + mandatoryCondition = Boolean.FALSE.toString(); + + accountid = getBooleanAsInteger(false); + password = getBooleanAsInteger(false); + } + + @Override + public String getExtAttrName() { + return extAttrName; + } + + @Override + public void setExtAttrName(final String extAttrName) { + this.extAttrName = extAttrName; + } + + @Override + public String getMandatoryCondition() { + return mandatoryCondition; + } + + @Override + public void setMandatoryCondition(final String mandatoryCondition) { + this.mandatoryCondition = mandatoryCondition; + } + + @Override + public String getIntAttrName() { + final String name; + + switch (getIntMappingType()) { + case UserId: + case RoleId: + case MembershipId: + name = "id"; + break; + + case Username: + name = "username"; + break; + + case Password: + name = "password"; + break; + + case RoleName: + name = "roleName"; + break; + + case RoleOwnerSchema: + name = "roleOwnerSchema"; + break; + + default: + name = intAttrName; + } + + return name; + } + + @Override + public void setIntAttrName(final String intAttrName) { + this.intAttrName = intAttrName; + } + + @Override + public IntMappingType getIntMappingType() { + return intMappingType; + } + + @Override + public void setIntMappingType(final IntMappingType intMappingType) { + this.intMappingType = intMappingType; + } + + @Override + public boolean isAccountid() { + return isBooleanAsInteger(accountid); + } + + @Override + public void setAccountid(final boolean accountid) { + this.accountid = getBooleanAsInteger(accountid); + } + + @Override + public boolean isPassword() { + return isBooleanAsInteger(password); + } + + @Override + public void setPassword(final boolean password) { + this.password = getBooleanAsInteger(password); + } + + @Override + public MappingPurpose getPurpose() { + return purpose; + } + + @Override + public void setPurpose(final MappingPurpose purpose) { + this.purpose = purpose; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java new file mode 100644 index 0000000..659b7f1 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttr.java @@ -0,0 +1,81 @@ +/* + * 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.entity; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.persistence.MappedSuperclass; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +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.PlainAttrUniqueValue; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrCheck; + +@MappedSuperclass +@PlainAttrCheck +public abstract class AbstractPlainAttr extends AbstractEntity<Long> implements PlainAttr { + + private static final long serialVersionUID = -9115431608821806124L; + + protected abstract boolean addValue(PlainAttrValue attrValue); + + @Override + public void addValue(final String value, final AttributableUtil attributableUtil) + throws InvalidPlainAttrValueException { + + PlainAttrValue attrValue; + if (getSchema().isUniqueConstraint()) { + attrValue = attributableUtil.newPlainAttrUniqueValue(); + ((PlainAttrUniqueValue) attrValue).setSchema(getSchema()); + } else { + attrValue = attributableUtil.newPlainAttrValue(); + } + + attrValue.setAttr(this); + getSchema().getValidator().validate(value, attrValue); + + if (getSchema().isUniqueConstraint()) { + setUniqueValue((PlainAttrUniqueValue) attrValue); + } else { + if (!getSchema().isMultivalue()) { + getValues().clear(); + } + addValue(attrValue); + } + } + + @Override + public List<String> getValuesAsStrings() { + List<String> result; + if (getUniqueValue() == null) { + result = new ArrayList<>(getValues().size()); + for (PlainAttrValue attributeValue : getValues()) { + result.add(attributeValue.getValueAsString()); + } + } else { + result = Collections.singletonList(getUniqueValue().getValueAsString()); + } + + return result; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java new file mode 100644 index 0000000..a6777a1 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrTemplate.java @@ -0,0 +1,27 @@ +/* + * 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.entity; + +import org.apache.syncope.core.persistence.api.entity.PlainSchema; + +public abstract class AbstractPlainAttrTemplate<P extends PlainSchema> extends AbstractAttrTemplate<P> { + + private static final long serialVersionUID = -943169893494860655L; + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java new file mode 100644 index 0000000..4977dad --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainAttrValue.java @@ -0,0 +1,282 @@ +/* + * 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.entity; + +import java.util.Date; +import javax.persistence.Basic; +import javax.persistence.Lob; +import javax.persistence.MappedSuperclass; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.core.persistence.api.attrvalue.validation.InvalidPlainAttrValueException; +import org.apache.syncope.core.persistence.api.attrvalue.validation.ParsingValidationException; +import org.apache.syncope.core.persistence.api.entity.PlainAttrValue; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.misc.DataFormat; +import org.apache.syncope.core.persistence.jpa.validation.entity.PlainAttrValueCheck; +import org.apache.syncope.core.misc.security.Encryptor; + +@MappedSuperclass +@PlainAttrValueCheck +public abstract class AbstractPlainAttrValue extends AbstractEntity<Long> implements PlainAttrValue { + + private static final long serialVersionUID = -9141923816611244785L; + + private String stringValue; + + @Temporal(TemporalType.TIMESTAMP) + private Date dateValue; + + @Basic + @Min(0) + @Max(1) + private Integer booleanValue; + + private Long longValue; + + private Double doubleValue; + + @Lob + private byte[] binaryValue; + + @Override + public Boolean getBooleanValue() { + return booleanValue == null + ? null + : isBooleanAsInteger(booleanValue); + } + + @Override + public void setBooleanValue(final Boolean booleanValue) { + this.booleanValue = booleanValue == null + ? null + : getBooleanAsInteger(booleanValue); + } + + @Override + public Date getDateValue() { + return dateValue == null + ? null + : new Date(dateValue.getTime()); + } + + @Override + public void setDateValue(final Date dateValue) { + this.dateValue = dateValue == null + ? null + : new Date(dateValue.getTime()); + } + + @Override + public Double getDoubleValue() { + return doubleValue; + } + + @Override + public void setDoubleValue(final Double doubleValue) { + this.doubleValue = doubleValue; + } + + @Override + public Long getLongValue() { + return longValue; + } + + @Override + public void setLongValue(final Long longValue) { + this.longValue = longValue; + } + + @Override + public String getStringValue() { + return stringValue; + } + + @Override + public void setStringValue(final String stringValue) { + this.stringValue = stringValue; + } + + @Override + public byte[] getBinaryValue() { + return binaryValue; + } + + @Override + public void setBinaryValue(final byte[] binaryValue) { + this.binaryValue = ArrayUtils.clone(binaryValue); + } + + @Override + public void parseValue(final PlainSchema schema, final String value) throws ParsingValidationException { + Exception exception = null; + + switch (schema.getType()) { + + case Boolean: + this.setBooleanValue(Boolean.parseBoolean(value)); + break; + + case Long: + try { + this.setLongValue(schema.getConversionPattern() == null + ? Long.valueOf(value) + : DataFormat.parseNumber(value, schema.getConversionPattern()).longValue()); + } catch (Exception pe) { + exception = pe; + } + break; + + case Double: + try { + this.setDoubleValue(schema.getConversionPattern() == null + ? Double.valueOf(value) + : DataFormat.parseNumber(value, schema.getConversionPattern()).doubleValue()); + } catch (Exception pe) { + exception = pe; + } + break; + + case Date: + try { + this.setDateValue(schema.getConversionPattern() == null + ? DataFormat.parseDate(value) + : new Date(DataFormat.parseDate(value, schema.getConversionPattern()).getTime())); + } catch (Exception pe) { + exception = pe; + } + break; + + case Encrypted: + try { + this.setStringValue(Encryptor.getInstance(schema.getSecretKey()). + encode(value, schema.getCipherAlgorithm())); + } catch (Exception pe) { + exception = pe; + } + break; + + case Binary: + this.setBinaryValue(Base64.decodeBase64(value)); + break; + + case String: + case Enum: + default: + this.setStringValue(value); + } + + if (exception != null) { + throw new ParsingValidationException("While trying to parse '" + value + "' as " + schema.getKey(), + exception); + } + } + + @SuppressWarnings("unchecked") + @Override + public <T> T getValue() { + return (T) (booleanValue != null + ? getBooleanValue() + : dateValue != null + ? getDateValue() + : doubleValue != null + ? getDoubleValue() + : longValue != null + ? getLongValue() + : binaryValue != null + ? getBinaryValue() + : stringValue); + } + + @Override + public String getValueAsString() { + final AttrSchemaType type = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getType() == null + ? AttrSchemaType.String + : getAttr().getSchema().getType(); + + return getValueAsString(type); + } + + @Override + public String getValueAsString(final AttrSchemaType type) { + Exception exception = null; + + String result = null; + + switch (type) { + + case Boolean: + result = getBooleanValue().toString(); + break; + + case Long: + result = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getConversionPattern() == null + ? getLongValue().toString() + : DataFormat.format(getLongValue(), getAttr().getSchema().getConversionPattern()); + break; + + case Double: + result = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getConversionPattern() == null + ? getDoubleValue().toString() + : DataFormat.format(getDoubleValue(), getAttr().getSchema().getConversionPattern()); + break; + + case Date: + result = getAttr() == null || getAttr().getSchema() == null + || getAttr().getSchema().getConversionPattern() == null + ? DataFormat.format(getDateValue()) + : DataFormat.format(getDateValue(), false, getAttr().getSchema(). + getConversionPattern()); + break; + + case Binary: + result = new String(Base64.encodeBase64String(getBinaryValue())); + break; + + case String: + case Enum: + case Encrypted: + default: + result = getStringValue(); + break; + } + + if (exception != null) { + throw new InvalidPlainAttrValueException( + "While trying to format '" + getValue() + "' as " + type, exception); + } + + return result; + } + + @Override + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.MULTI_LINE_STYLE); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java ---------------------------------------------------------------------- diff --git a/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java new file mode 100644 index 0000000..cf0a3c9 --- /dev/null +++ b/syncope620/core/persistence-jpa/src/main/java/org/apache/syncope/core/persistence/jpa/entity/AbstractPlainSchema.java @@ -0,0 +1,272 @@ +/* + * 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.entity; + +import java.lang.reflect.Constructor; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.MappedSuperclass; +import javax.persistence.Transient; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.common.lib.types.AttrSchemaType; +import org.apache.syncope.common.lib.types.CipherAlgorithm; +import org.apache.syncope.core.persistence.api.attrvalue.validation.Validator; +import org.apache.syncope.core.persistence.api.entity.PlainSchema; +import org.apache.syncope.core.persistence.jpa.attrvalue.validation.BasicValidator; +import org.apache.syncope.core.persistence.jpa.validation.entity.PlainSchemaCheck; +import org.apache.syncope.core.persistence.jpa.validation.entity.SchemaNameCheck; + +@MappedSuperclass +@PlainSchemaCheck +@SchemaNameCheck +public abstract class AbstractPlainSchema extends AbstractEntity<String> implements PlainSchema { + + private static final long serialVersionUID = -8621028596062054739L; + + @Id + private String name; + + @Column(nullable = false) + @Enumerated(EnumType.STRING) + private AttrSchemaType type; + + @Column(nullable = false) + private String mandatoryCondition; + + @Basic + @Min(0) + @Max(1) + private Integer multivalue; + + @Basic + @Min(0) + @Max(1) + private Integer uniqueConstraint; + + @Basic + @Min(0) + @Max(1) + private Integer readonly; + + @Column(nullable = true) + private String conversionPattern; + + @Column(nullable = true) + private String validatorClass; + + @Column(nullable = true) + @Lob + private String enumerationValues; + + @Column(nullable = true) + @Lob + private String enumerationKeys; + + @Column(nullable = true) + private String secretKey; + + @Column(nullable = true) + @Enumerated(EnumType.STRING) + private CipherAlgorithm cipherAlgorithm; + + @Column(nullable = true) + private String mimeType; + + @Transient + private Validator validator; + + public AbstractPlainSchema() { + super(); + + type = AttrSchemaType.String; + mandatoryCondition = Boolean.FALSE.toString(); + multivalue = getBooleanAsInteger(false); + uniqueConstraint = getBooleanAsInteger(false); + readonly = getBooleanAsInteger(false); + } + + @Override + public String getKey() { + return name; + } + + @Override + public void setKey(final String name) { + this.name = name; + } + + @Override + public AttrSchemaType getType() { + return type; + } + + @Override + public void setType(final AttrSchemaType type) { + this.type = type; + } + + @Override + public String getMandatoryCondition() { + return mandatoryCondition; + } + + @Override + public void setMandatoryCondition(final String condition) { + this.mandatoryCondition = condition; + } + + @Override + public boolean isMultivalue() { + return isBooleanAsInteger(multivalue); + } + + @Override + public void setMultivalue(boolean multivalue) { + this.multivalue = getBooleanAsInteger(multivalue); + } + + @Override + public boolean isUniqueConstraint() { + return isBooleanAsInteger(uniqueConstraint); + } + + @Override + public void setUniqueConstraint(final boolean uniquevalue) { + this.uniqueConstraint = getBooleanAsInteger(uniquevalue); + } + + @Override + public boolean isReadonly() { + return isBooleanAsInteger(readonly); + } + + @Override + public void setReadonly(final boolean readonly) { + this.readonly = getBooleanAsInteger(readonly); + } + + @Override + public Validator getValidator() { + if (validator != null) { + return validator; + } + + if (getValidatorClass() != null && getValidatorClass().length() > 0) { + try { + Constructor<?> validatorConstructor = Class.forName(getValidatorClass()). + getConstructor(new Class<?>[] { PlainSchema.class }); + validator = (Validator) validatorConstructor.newInstance(this); + } catch (Exception e) { + LOG.error("Could not instantiate validator of type {}, reverting to {}", + getValidatorClass(), BasicValidator.class.getSimpleName(), e); + } + } + + if (validator == null) { + validator = new BasicValidator(this); + } + + return validator; + } + + @Override + public String getValidatorClass() { + return validatorClass; + } + + @Override + public void setValidatorClass(final String validatorClass) { + this.validatorClass = validatorClass; + } + + @Override + public String getEnumerationValues() { + return enumerationValues; + } + + @Override + public void setEnumerationValues(final String enumerationValues) { + this.enumerationValues = enumerationValues; + } + + @Override + public String getEnumerationKeys() { + return enumerationKeys; + } + + @Override + public void setEnumerationKeys(String enumerationKeys) { + this.enumerationKeys = enumerationKeys; + } + + @Override + public String getConversionPattern() { + if (!getType().isConversionPatternNeeded()) { + LOG.debug("Conversion pattern is not needed: {}'s type is {}", this, getType()); + } + + return conversionPattern; + } + + @Override + public void setConversionPattern(final String conversionPattern) { + if (StringUtils.isNotBlank(conversionPattern) && !getType().isConversionPatternNeeded()) { + LOG.warn("Conversion pattern will be ignored: this attribute type is {}", getType()); + } + + this.conversionPattern = conversionPattern; + } + + @Override + public String getSecretKey() { + return secretKey; + } + + @Override + public void setSecretKey(final String secretKey) { + this.secretKey = secretKey; + } + + @Override + public CipherAlgorithm getCipherAlgorithm() { + return cipherAlgorithm; + } + + @Override + public void setCipherAlgorithm(final CipherAlgorithm cipherAlgorithm) { + this.cipherAlgorithm = cipherAlgorithm; + } + + @Override + public String getMimeType() { + return mimeType; + } + + @Override + public void setMimeType(final String mimeType) { + this.mimeType = mimeType; + } + +}
