/* * Copyright (c) 2010-2013 Evolveum * * Licensed 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 com.evolveum.midpoint.repo.sql.data.common.container; import com.evolveum.midpoint.repo.sql.data.RepositoryContext; import com.evolveum.midpoint.repo.sql.data.common.Metadata; import com.evolveum.midpoint.repo.sql.data.common.RObject; import com.evolveum.midpoint.repo.sql.data.common.any.RAssignmentExtension; import com.evolveum.midpoint.repo.sql.data.common.embedded.RActivation; import com.evolveum.midpoint.repo.sql.data.common.embedded.REmbeddedReference; import com.evolveum.midpoint.repo.sql.data.common.id.RContainerId; import com.evolveum.midpoint.repo.sql.data.common.other.RAssignmentOwner; import com.evolveum.midpoint.repo.sql.data.common.type.RAssignmentExtensionType; import com.evolveum.midpoint.repo.sql.data.factory.MetadataFactory; import com.evolveum.midpoint.repo.sql.query.definition.JaxbName; import com.evolveum.midpoint.repo.sql.query.definition.JaxbPath; import com.evolveum.midpoint.repo.sql.query.definition.JaxbType; import com.evolveum.midpoint.repo.sql.query.definition.OwnerIdGetter; import com.evolveum.midpoint.repo.sql.query.definition.QueryEntity; import com.evolveum.midpoint.repo.sql.query2.definition.IdQueryProperty; import com.evolveum.midpoint.repo.sql.query2.definition.NotQueryable; import com.evolveum.midpoint.repo.sql.util.DtoTranslationException; import com.evolveum.midpoint.repo.sql.util.IdGeneratorResult; import com.evolveum.midpoint.repo.sql.util.MidPointSingleTablePersister; import com.evolveum.midpoint.repo.sql.util.RUtil; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import org.apache.commons.lang.Validate; import org.hibernate.annotations.*; import javax.persistence.*; import javax.persistence.Entity; import javax.persistence.ForeignKey; import javax.persistence.Index; import javax.persistence.Table; import javax.xml.datatype.XMLGregorianCalendar; import java.util.HashSet; import java.util.Set; /** * @author lazyman */ @JaxbType(type = AssignmentType.class) @Entity @QueryEntity( entities = { // @VirtualEntity( // jaxbName = @JaxbName(localPart = "metadata"), // jaxbType = MetadataType.class, // jpaName = "", // jpaType = Serializable.class // dummy value (ignored) // ) // , // @VirtualEntity( // jaxbName = @JaxbName(localPart = "construction"), // jaxbType = ConstructionType.class, // jpaName = "", // jpaType = Serializable.class // dummy value (ignored) // ) } ) @IdClass(RContainerId.class) // TODO prefix last 4 index names with "iAssignment" (some day) @Table(name = "m_assignment", indexes = { @Index(name = "iAssignmentAdministrative", columnList = "administrativeStatus"), @Index(name = "iAssignmentEffective", columnList = "effectiveStatus"), @Index(name = "iTargetRefTargetOid", columnList = "targetRef_targetOid"), @Index(name = "iTenantRefTargetOid", columnList = "tenantRef_targetOid"), @Index(name = "iOrgRefTargetOid", columnList = "orgRef_targetOid"), @Index(name = "iResourceRefTargetOid", columnList = "resourceRef_targetOid")}) @Persister(impl = MidPointSingleTablePersister.class) public class RAssignment implements Container, Metadata<RAssignmentReference> { public static final String F_OWNER = "owner"; /** * enum identifier of object class which owns this assignment. It's used because we have to * distinguish between assignments and inducements (all of them are the same kind) in {@link com.evolveum.midpoint.repo.sql.data.common.RAbstractRole}. */ public static final String F_ASSIGNMENT_OWNER = "assignmentOwner"; private static final Trace LOGGER = TraceManager.getTrace(RAssignment.class); private Boolean trans; private RObject owner; private String ownerOid; private Integer id; private RAssignmentOwner assignmentOwner; //extension private RAssignmentExtension extension; //assignment fields private RActivation activation; private REmbeddedReference targetRef; private Integer order; private REmbeddedReference tenantRef; private REmbeddedReference orgRef; private REmbeddedReference resourceRef; private String lifecycleState; private Set<String> policySituation; //metadata private XMLGregorianCalendar createTimestamp; private REmbeddedReference creatorRef; private Set<RAssignmentReference> createApproverRef; private String createChannel; private XMLGregorianCalendar modifyTimestamp; private REmbeddedReference modifierRef; private Set<RAssignmentReference> modifyApproverRef; private String modifyChannel; public RAssignment() { this(null, null); } public RAssignment(RObject owner, RAssignmentOwner assignmentOwner) { this.setOwner(owner); this.assignmentOwner = assignmentOwner; } @Id @org.hibernate.annotations.ForeignKey(name = "fk_assignment_owner") @MapsId("owner") @ManyToOne(fetch = FetchType.LAZY) // @JoinTable(foreignKey = @ForeignKey(name = "fk_assignment_owner")) @NotQueryable public RObject getOwner() { return owner; } @Column(name = "owner_oid", length = RUtil.COLUMN_LENGTH_OID, nullable = false) @OwnerIdGetter() public String getOwnerOid() { if (owner != null && ownerOid == null) { ownerOid = owner.getOid(); } return ownerOid; } @Id @GeneratedValue(generator = "ContainerIdGenerator") @GenericGenerator(name = "ContainerIdGenerator", strategy = "com.evolveum.midpoint.repo.sql.util.ContainerIdGenerator") @Column(name = "id") @IdQueryProperty public Integer getId() { return id; } @Enumerated(EnumType.ORDINAL) public RAssignmentOwner getAssignmentOwner() { return assignmentOwner; } @Embedded public REmbeddedReference getTargetRef() { return targetRef; } @Embedded public REmbeddedReference getTenantRef() { return tenantRef; } @Embedded public REmbeddedReference getOrgRef() { return orgRef; } @Embedded @JaxbPath(itemPath = { @JaxbName(localPart = "construction"), @JaxbName(localPart = "resourceRef") }) public REmbeddedReference getResourceRef() { return resourceRef; } @org.hibernate.annotations.ForeignKey(name = "none") @com.evolveum.midpoint.repo.sql.query.definition.Any(jaxbNameLocalPart = "extension") @OneToOne(optional = true, orphanRemoval = true) @Cascade({org.hibernate.annotations.CascadeType.ALL}) @JoinColumns(value = { @JoinColumn(name = "extOid", referencedColumnName = "owner_owner_oid"), @JoinColumn(name = "extId", referencedColumnName = "owner_id") }, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) public RAssignmentExtension getExtension() { return extension; } @Embedded public RActivation getActivation() { return activation; } @Column(name = "orderValue") public Integer getOrder() { return order; } @Where(clause = RAssignmentReference.REFERENCE_TYPE + "= 0") @OneToMany(mappedBy = RAssignmentReference.F_OWNER, orphanRemoval = true) @org.hibernate.annotations.ForeignKey(name = "none") @Cascade({org.hibernate.annotations.CascadeType.ALL}) //@JoinTable(foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT)) @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "createApproverRef") }) public Set<RAssignmentReference> getCreateApproverRef() { if (createApproverRef == null) { createApproverRef = new HashSet<>(); } return createApproverRef; } @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "createChannel") }) public String getCreateChannel() { return createChannel; } @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "createTimestamp") }) public XMLGregorianCalendar getCreateTimestamp() { return createTimestamp; } @Embedded @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "creatorRef") }) public REmbeddedReference getCreatorRef() { return creatorRef; } @Embedded @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "modifierRef") }) public REmbeddedReference getModifierRef() { return modifierRef; } @Where(clause = RAssignmentReference.REFERENCE_TYPE + "= 1") @OneToMany(mappedBy = RAssignmentReference.F_OWNER, orphanRemoval = true) // @JoinTable(foreignKey = @ForeignKey(name = "none")) @Cascade({org.hibernate.annotations.CascadeType.ALL}) @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "modifyApproverRef") }) public Set<RAssignmentReference> getModifyApproverRef() { if (modifyApproverRef == null) { modifyApproverRef = new HashSet<>(); } return modifyApproverRef; } @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "modifyChannel") }) public String getModifyChannel() { return modifyChannel; } @JaxbPath(itemPath = { @JaxbName(localPart = "metadata"), @JaxbName(localPart = "modifyTimestamp") }) public XMLGregorianCalendar getModifyTimestamp() { return modifyTimestamp; } @Transient @Override public Boolean isTransient() { return trans; } public String getLifecycleState() { return lifecycleState; } @ElementCollection @org.hibernate.annotations.ForeignKey(name = "fk_assignment_policy_situation") @CollectionTable(name = "m_assignment_policy_situation", joinColumns = { @JoinColumn(name = "assignment_oid", referencedColumnName = "owner_oid"), @JoinColumn(name = "assignment_id", referencedColumnName = "id") }) @Cascade({org.hibernate.annotations.CascadeType.ALL}) public Set<String> getPolicySituation() { return policySituation; } public void setPolicySituation(Set<String> policySituation) { this.policySituation = policySituation; } public void setLifecycleState(String lifecycleState) { this.lifecycleState = lifecycleState; } @Override public void setTransient(Boolean trans) { this.trans = trans; } public void setOwner(RObject owner) { this.owner = owner; } public void setOwnerOid(String ownerOid) { this.ownerOid = ownerOid; } public void setId(Integer id) { this.id = id; } public void setCreateApproverRef(Set<RAssignmentReference> createApproverRef) { this.createApproverRef = createApproverRef; } public void setCreateChannel(String createChannel) { this.createChannel = createChannel; } public void setCreateTimestamp(XMLGregorianCalendar createTimestamp) { this.createTimestamp = createTimestamp; } public void setCreatorRef(REmbeddedReference creatorRef) { this.creatorRef = creatorRef; } public void setModifierRef(REmbeddedReference modifierRef) { this.modifierRef = modifierRef; } public void setModifyApproverRef(Set<RAssignmentReference> modifyApproverRef) { this.modifyApproverRef = modifyApproverRef; } public void setModifyChannel(String modifyChannel) { this.modifyChannel = modifyChannel; } public void setModifyTimestamp(XMLGregorianCalendar modifyTimestamp) { this.modifyTimestamp = modifyTimestamp; } public void setOrder(Integer order) { this.order = order; } public void setActivation(RActivation activation) { this.activation = activation; } public void setExtension(RAssignmentExtension extension) { this.extension = extension; } public void setTargetRef(REmbeddedReference targetRef) { this.targetRef = targetRef; } public void setAssignmentOwner(RAssignmentOwner assignmentOwner) { this.assignmentOwner = assignmentOwner; } public void setTenantRef(REmbeddedReference tenantRef) { this.tenantRef = tenantRef; } public void setOrgRef(REmbeddedReference orgRef) { this.orgRef = orgRef; } public void setResourceRef(REmbeddedReference resourceRef) { this.resourceRef = resourceRef; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; RAssignment that = (RAssignment) o; if (activation != null ? !activation.equals(that.activation) : that.activation != null) return false; if (extension != null ? !extension.equals(that.extension) : that.extension != null) return false; if (targetRef != null ? !targetRef.equals(that.targetRef) : that.targetRef != null) return false; if (assignmentOwner != null ? !assignmentOwner.equals(that.assignmentOwner) : that.assignmentOwner != null) return false; if (order != null ? !order.equals(that.order) : that.order != null) return false; if (tenantRef != null ? !tenantRef.equals(that.tenantRef) : that.tenantRef != null) return false; if (orgRef != null ? !orgRef.equals(that.orgRef) : that.orgRef != null) return false; if (resourceRef != null ? !resourceRef.equals(that.resourceRef) : that.resourceRef != null) return false; if (lifecycleState != null ? !lifecycleState.equals(that.lifecycleState) : that.lifecycleState != null) return false; if (policySituation != null ? !policySituation.equals(that.policySituation) : that.policySituation != null) return false; if (!MetadataFactory.equals(this, that)) return false; return true; } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (activation != null ? activation.hashCode() : 0); result = 31 * result + (order != null ? order.hashCode() : 0); result = 31 * result + (createTimestamp != null ? createTimestamp.hashCode() : 0); result = 31 * result + (creatorRef != null ? creatorRef.hashCode() : 0); result = 31 * result + (createChannel != null ? createChannel.hashCode() : 0); result = 31 * result + (modifyTimestamp != null ? modifyTimestamp.hashCode() : 0); result = 31 * result + (modifierRef != null ? modifierRef.hashCode() : 0); result = 31 * result + (modifyChannel != null ? modifyChannel.hashCode() : 0); result = 31 * result + (lifecycleState != null ? lifecycleState.hashCode() : 0); return result; } public static void copyFromJAXB(AssignmentType jaxb, RAssignment repo, ObjectType parent, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { Validate.notNull(repo, "Repo object must not be null."); Validate.notNull(jaxb, "JAXB object must not be null."); repo.setTransient(generatorResult.isTransient(jaxb.asPrismContainerValue())); repo.setOwnerOid(parent.getOid()); repo.setId(RUtil.toInteger(jaxb.getId())); repo.setOrder(jaxb.getOrder()); repo.setLifecycleState(jaxb.getLifecycleState()); repo.setPolicySituation(RUtil.listToSet(jaxb.getPolicySituation())); if (jaxb.getExtension() != null) { RAssignmentExtension extension = new RAssignmentExtension(); extension.setOwner(repo); repo.setExtension(extension); RAssignmentExtension.copyFromJAXB(jaxb.getExtension(), extension, RAssignmentExtensionType.EXTENSION, repositoryContext); } if (jaxb.getActivation() != null) { RActivation activation = new RActivation(); RActivation.copyFromJAXB(jaxb.getActivation(), activation, repositoryContext); repo.setActivation(activation); } if (jaxb.getTarget() != null) { LOGGER.warn("Target from assignment type won't be saved. It should be translated to target reference."); } repo.setTargetRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTargetRef(), repositoryContext.prismContext)); repo.setTenantRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getTenantRef(), repositoryContext.prismContext)); repo.setOrgRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getOrgRef(), repositoryContext.prismContext)); if (jaxb.getConstruction() != null) { repo.setResourceRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getConstruction().getResourceRef(), repositoryContext.prismContext)); } MetadataFactory.fromJAXB(jaxb.getMetadata(), repo, repositoryContext.prismContext); } @Override public String toString() { return "RAssignment{" + "id=" + id + ", ownerOid='" + ownerOid + '\'' + ", owner=" + owner + ", targetRef=" + targetRef + ", resourceRef=" + resourceRef + '}'; } }