/*
* 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;
import com.evolveum.midpoint.repo.sql.data.RepositoryContext;
import com.evolveum.midpoint.repo.sql.data.common.container.RAssignment;
import com.evolveum.midpoint.repo.sql.data.common.embedded.RActivation;
import com.evolveum.midpoint.repo.sql.data.common.other.RAssignmentOwner;
import com.evolveum.midpoint.repo.sql.data.common.other.RReferenceOwner;
import com.evolveum.midpoint.repo.sql.query.definition.JaxbName;
import com.evolveum.midpoint.repo.sql.query.definition.QueryEntity;
import com.evolveum.midpoint.repo.sql.query.definition.VirtualCollection;
import com.evolveum.midpoint.repo.sql.query.definition.VirtualQueryParam;
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.MidPointJoinedPersister;
import com.evolveum.midpoint.repo.sql.util.RUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import org.hibernate.annotations.*;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.Index;
import javax.persistence.*;
import javax.persistence.Entity;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* @author lazyman
*/
@QueryEntity(collections = {
@VirtualCollection(jaxbName = @JaxbName(localPart = "assignment"), jaxbType = Set.class,
jpaName = "assignments", jpaType = Set.class, additionalParams = {
@VirtualQueryParam(name = "assignmentOwner", type = RAssignmentOwner.class,
value = "FOCUS")}, collectionType = RAssignment.class)})
@Entity
@ForeignKey(name = "fk_focus")
@org.hibernate.annotations.Table(appliesTo = "m_focus",
indexes = {@Index(name = "iFocusAdministrative", columnNames = "administrativeStatus"),
@Index(name = "iFocusEffective", columnNames = "effectiveStatus")})
@Persister(impl = MidPointJoinedPersister.class)
public abstract class RFocus<T extends FocusType> extends RObject<T> {
private Set<RObjectReference<RShadow>> linkRef;
private Set<RObjectReference<RAbstractRole>> roleMembershipRef;
private Set<RObjectReference<RFocus>> delegatedRef;
private Set<RObjectReference<RFocus>> personaRef;
private Set<RAssignment> assignments;
private RActivation activation;
private Set<String> policySituation;
//photo
private boolean hasPhoto;
private Set<RFocusPhoto> jpegPhoto;
@Where(clause = RObjectReference.REFERENCE_TYPE + "= 1")
@OneToMany(mappedBy = "owner", orphanRemoval = true)
@ForeignKey(name = "none")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Set<RObjectReference<RShadow>> getLinkRef() {
if (linkRef == null) {
linkRef = new HashSet<>();
}
return linkRef;
}
@Where(clause = RObjectReference.REFERENCE_TYPE + "= 8")
@OneToMany(mappedBy = "owner", orphanRemoval = true)
@ForeignKey(name = "none")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Set<RObjectReference<RAbstractRole>> getRoleMembershipRef() {
if (roleMembershipRef == null) {
roleMembershipRef = new HashSet<>();
}
return roleMembershipRef;
}
@Where(clause = RObjectReference.REFERENCE_TYPE + "= 9")
@OneToMany(mappedBy = "owner", orphanRemoval = true)
@ForeignKey(name = "none")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Set<RObjectReference<RFocus>> getDelegatedRef() {
if (delegatedRef == null) {
delegatedRef = new HashSet<>();
}
return delegatedRef;
}
@Where(clause = RObjectReference.REFERENCE_TYPE + "= 10")
@OneToMany(mappedBy = "owner", orphanRemoval = true)
@ForeignKey(name = "none")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Set<RObjectReference<RFocus>> getPersonaRef() {
if (personaRef == null) {
personaRef = new HashSet<>();
}
return personaRef;
}
@Transient
protected Set<RAssignment> getAssignments(RAssignmentOwner owner) {
Set<RAssignment> assignments = getAssignments();
Set<RAssignment> wanted = new HashSet<>();
if (assignments == null) {
return wanted;
}
Iterator<RAssignment> iterator = assignments.iterator();
while (iterator.hasNext()) {
RAssignment ass = iterator.next();
if (owner.equals(ass.getAssignmentOwner())) {
wanted.add(ass);
}
}
return wanted;
}
@Transient
public Set<RAssignment> getAssignment() {
return getAssignments(RAssignmentOwner.FOCUS);
}
@OneToMany(mappedBy = RAssignment.F_OWNER, orphanRemoval = true)
@ForeignKey(name = "none")
@Cascade({org.hibernate.annotations.CascadeType.ALL})
@NotQueryable // virtual definition is used instead
public Set<RAssignment> getAssignments() {
if (assignments == null) {
assignments = new HashSet<>();
}
return assignments;
}
@Embedded
public RActivation getActivation() {
return activation;
}
@ElementCollection
@ForeignKey(name = "fk_focus_policy_situation")
@CollectionTable(name = "m_focus_policy_situation", joinColumns = {
@JoinColumn(name = "focus_oid", referencedColumnName = "oid")
})
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Set<String> getPolicySituation() {
return policySituation;
}
public void setPolicySituation(Set<String> policySituation) {
this.policySituation = policySituation;
}
public void setAssignments(Set<RAssignment> assignments) {
this.assignments = assignments;
}
public void setLinkRef(Set<RObjectReference<RShadow>> linkRef) {
this.linkRef = linkRef;
}
public void setRoleMembershipRef(Set<RObjectReference<RAbstractRole>> roleMembershipRef) {
this.roleMembershipRef = roleMembershipRef;
}
public void setDelegatedRef(Set<RObjectReference<RFocus>> delegatedRef) {
this.delegatedRef = delegatedRef;
}
public void setPersonaRef(Set<RObjectReference<RFocus>> personaRef) {
this.personaRef = personaRef;
}
public void setActivation(RActivation activation) {
this.activation = activation;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
RFocus other = (RFocus) o;
if (assignments != null ? !assignments.equals(other.assignments) : other.assignments != null) return false;
if (linkRef != null ? !linkRef.equals(other.linkRef) : other.linkRef != null) return false;
if (roleMembershipRef != null ? !roleMembershipRef.equals(other.roleMembershipRef) : other.roleMembershipRef != null) return false;
if (activation != null ? !activation.equals(other.activation) : other.activation != null) return false;
if (policySituation != null ? !policySituation.equals(other.policySituation) : other.policySituation != null) return false;
return true;
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (activation != null ? activation.hashCode() : 0);
return result;
}
public static <T extends FocusType> void copyFromJAXB(FocusType jaxb, RFocus<T> repo, RepositoryContext repositoryContext,
IdGeneratorResult generatorResult)
throws DtoTranslationException {
RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult);
repo.getLinkRef().addAll(
RUtil.safeListReferenceToSet(jaxb.getLinkRef(), repositoryContext.prismContext, repo, RReferenceOwner.USER_ACCOUNT));
repo.getRoleMembershipRef().addAll(
RUtil.safeListReferenceToSet(jaxb.getRoleMembershipRef(), repositoryContext.prismContext, repo, RReferenceOwner.ROLE_MEMBER));
repo.getDelegatedRef().addAll(
RUtil.safeListReferenceToSet(jaxb.getDelegatedRef(), repositoryContext.prismContext, repo, RReferenceOwner.DELEGATED));
repo.getPersonaRef().addAll(
RUtil.safeListReferenceToSet(jaxb.getPersonaRef(), repositoryContext.prismContext, repo, RReferenceOwner.PERSONA));
repo.setPolicySituation(RUtil.listToSet(jaxb.getPolicySituation()));
for (AssignmentType assignment : jaxb.getAssignment()) {
RAssignment rAssignment = new RAssignment(repo, RAssignmentOwner.FOCUS);
RAssignment.copyFromJAXB(assignment, rAssignment, jaxb, repositoryContext, generatorResult);
repo.getAssignments().add(rAssignment);
}
if (jaxb.getActivation() != null) {
RActivation activation = new RActivation();
RActivation.copyFromJAXB(jaxb.getActivation(), activation, repositoryContext);
repo.setActivation(activation);
}
if (jaxb.getJpegPhoto() != null) {
RFocusPhoto photo = new RFocusPhoto();
photo.setOwner(repo);
photo.setPhoto(jaxb.getJpegPhoto());
repo.getJpegPhoto().add(photo);
repo.setHasPhoto(true);
}
}
@ColumnDefault("false")
public boolean isHasPhoto() {
return hasPhoto;
}
// setting orphanRemoval = false prevents:
// (1) deletion of photos for RUsers that have no photos fetched (because fetching is lazy)
// (2) even querying of m_focus_photo table on RFocus merge
// (see comments in SqlRepositoryServiceImpl.modifyObjectAttempt)
@OneToMany(mappedBy = "owner", orphanRemoval = false)
@Cascade({org.hibernate.annotations.CascadeType.ALL})
public Set<RFocusPhoto> getJpegPhoto() {
if (jpegPhoto == null) {
jpegPhoto = new HashSet<>();
}
return jpegPhoto;
}
public void setHasPhoto(boolean hasPhoto) {
this.hasPhoto = hasPhoto;
}
public void setJpegPhoto(Set<RFocusPhoto> jpegPhoto) {
this.jpegPhoto = jpegPhoto;
}
}