/* * 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.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.repo.sql.data.RepositoryContext; import com.evolveum.midpoint.repo.sql.data.common.embedded.REmbeddedReference; import com.evolveum.midpoint.repo.sql.data.common.embedded.RPolyString; import com.evolveum.midpoint.repo.sql.data.common.enums.RFailedOperationType; import com.evolveum.midpoint.repo.sql.data.common.enums.ROperationResultStatus; import com.evolveum.midpoint.repo.sql.data.common.enums.RShadowKind; import com.evolveum.midpoint.repo.sql.data.common.enums.RSynchronizationSituation; import com.evolveum.midpoint.repo.sql.data.common.type.RObjectExtensionType; import com.evolveum.midpoint.repo.sql.query.definition.Count; import com.evolveum.midpoint.repo.sql.query.definition.QueryEntity; import com.evolveum.midpoint.repo.sql.query.definition.VirtualAny; 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.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import org.hibernate.annotations.ForeignKey; import org.hibernate.annotations.Index; import org.hibernate.annotations.Persister; import javax.persistence.*; import javax.xml.datatype.XMLGregorianCalendar; import java.util.Collection; import java.util.Objects; /** * @author lazyman */ @Entity @Table(name = "m_shadow") @org.hibernate.annotations.Table(appliesTo = "m_shadow", indexes = { @Index(name = "iShadowResourceRef", columnNames = "resourceRef_targetOid"), @Index(name = "iShadowDead", columnNames = "dead"), @Index(name = "iShadowKind", columnNames = "kind"), @Index(name = "iShadowIntent", columnNames = "intent"), @Index(name = "iShadowObjectClass", columnNames = "objectClass"), @Index(name = "iShadowFailedOperationType", columnNames = "failedOperationType"), @Index(name = "iShadowSyncSituation", columnNames = "synchronizationSituation"), @Index(name = "iShadowPendingOperationCount", columnNames = "pendingOperationCount") }) @ForeignKey(name = "fk_shadow") @QueryEntity(anyElements = { @VirtualAny(jaxbNameLocalPart = "attributes", ownerType = RObjectExtensionType.ATTRIBUTES)}) @Persister(impl = MidPointJoinedPersister.class) public class RShadow<T extends ShadowType> extends RObject<T> implements OperationResult { private static final Trace LOGGER = TraceManager.getTrace(RShadow.class); private RPolyString name; private String objectClass; //operation result private ROperationResultStatus status; //end of operation result private REmbeddedReference resourceRef; private Integer attemptNumber; private Boolean dead; private RFailedOperationType failedOperationType; private String intent; private RSynchronizationSituation synchronizationSituation; //attributes private XMLGregorianCalendar synchronizationTimestamp; private RShadowKind kind; private Boolean exists; private XMLGregorianCalendar fullSynchronizationTimestamp; private Integer pendingOperationCount; @Column(name = "exist") public Boolean isExists() { return exists; } @Enumerated(EnumType.ORDINAL) @Column(nullable = true) public RShadowKind getKind() { return kind; } @Column(length = RUtil.COLUMN_LENGTH_QNAME) public String getObjectClass() { return objectClass; } @Embedded public REmbeddedReference getResourceRef() { return resourceRef; } @Column(nullable = true) public Integer getAttemptNumber() { return attemptNumber; } @Enumerated(EnumType.ORDINAL) @Column(nullable = true) public RFailedOperationType getFailedOperationType() { return failedOperationType; } @Embedded public RPolyString getName() { return name; } @Enumerated(EnumType.ORDINAL) public RSynchronizationSituation getSynchronizationSituation() { return synchronizationSituation; } public Boolean isDead() { return dead; } public String getIntent() { return intent; } public XMLGregorianCalendar getSynchronizationTimestamp() { return synchronizationTimestamp; } public XMLGregorianCalendar getFullSynchronizationTimestamp() { return fullSynchronizationTimestamp; } @Enumerated(EnumType.ORDINAL) public ROperationResultStatus getStatus() { return status; } public void setStatus(ROperationResultStatus status) { this.status = status; } public void setFullSynchronizationTimestamp(XMLGregorianCalendar fullSynchronizationTimestamp) { this.fullSynchronizationTimestamp = fullSynchronizationTimestamp; } public void setSynchronizationTimestamp(XMLGregorianCalendar synchronizationTimestamp) { this.synchronizationTimestamp = synchronizationTimestamp; } public void setName(RPolyString name) { this.name = name; } public void setAttemptNumber(Integer attemptNumber) { this.attemptNumber = attemptNumber; } public void setFailedOperationType(RFailedOperationType failedOperationType) { this.failedOperationType = failedOperationType; } public void setKind(RShadowKind kind) { this.kind = kind; } public void setResourceRef(REmbeddedReference resourceRef) { this.resourceRef = resourceRef; } public void setObjectClass(String objectClass) { this.objectClass = objectClass; } public void setIntent(String intent) { this.intent = intent; } public void setSynchronizationSituation(RSynchronizationSituation synchronizationSituation) { this.synchronizationSituation = synchronizationSituation; } public void setDead(Boolean dead) { this.dead = dead; } public void setExists(Boolean exists) { this.exists = exists; } @Count public Integer getPendingOperationCount() { return pendingOperationCount; } public void setPendingOperationCount(Integer pendingOperationCount) { this.pendingOperationCount = pendingOperationCount; } @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; RShadow that = (RShadow) o; if (name != null ? !name.equals(that.name) : that.name != null) return false; if (attemptNumber != null ? !attemptNumber.equals(that.attemptNumber) : that.attemptNumber != null) return false; if (failedOperationType != that.failedOperationType) return false; if (objectClass != null ? !objectClass.equals(that.objectClass) : that.objectClass != null) return false; if (resourceRef != null ? !resourceRef.equals(that.resourceRef) : that.resourceRef != null) return false; if (intent != null ? !intent.equals(that.intent) : that.intent != null) return false; if (synchronizationSituation != null ? !synchronizationSituation.equals(that.synchronizationSituation) : that.synchronizationSituation != null) return false; if (kind != null ? !kind.equals(that.kind) : that.kind != null) return false; if (exists != null ? !exists.equals(that.exists) : that.exists != null) return false; if (status != that.status) return false; if (!Objects.equals(pendingOperationCount, that.pendingOperationCount)) return false; return true; } @Override public int hashCode() { int result1 = super.hashCode(); result1 = 31 * result1 + (name != null ? name.hashCode() : 0); result1 = 31 * result1 + (objectClass != null ? objectClass.hashCode() : 0); result1 = 31 * result1 + (attemptNumber != null ? attemptNumber.hashCode() : 0); result1 = 31 * result1 + (failedOperationType != null ? failedOperationType.hashCode() : 0); result1 = 31 * result1 + (intent != null ? intent.hashCode() : 0); result1 = 31 * result1 + (synchronizationSituation != null ? synchronizationSituation.hashCode() : 0); result1 = 31 * result1 + (kind != null ? kind.hashCode() : 0); result1 = 31 * result1 + (exists != null ? exists.hashCode() : 0); result1 = 31 * result1 + (fullSynchronizationTimestamp != null ? fullSynchronizationTimestamp.hashCode() : 0); result1 = 31 * result1 + (status != null ? status.hashCode() : 0); return result1; } public static <T extends ShadowType> void copyFromJAXB(ShadowType jaxb, RShadow<T> repo, RepositoryContext repositoryContext, IdGeneratorResult generatorResult) throws DtoTranslationException { RObject.copyFromJAXB(jaxb, repo, repositoryContext, generatorResult); repo.setName(RPolyString.copyFromJAXB(jaxb.getName())); repo.setObjectClass(RUtil.qnameToString(jaxb.getObjectClass())); repo.setIntent(jaxb.getIntent()); repo.setKind(RUtil.getRepoEnumValue(jaxb.getKind(), RShadowKind.class)); repo.setFullSynchronizationTimestamp(jaxb.getFullSynchronizationTimestamp()); ItemDefinition def = jaxb.asPrismObject().getDefinition(); RUtil.copyResultFromJAXB(def, ShadowType.F_RESULT, jaxb.getResult(), repo, repositoryContext.prismContext); if (jaxb.getSynchronizationSituation() != null) { repo.setSynchronizationSituation(RUtil.getRepoEnumValue(jaxb.getSynchronizationSituation(), RSynchronizationSituation.class)); } repo.setSynchronizationTimestamp(jaxb.getSynchronizationTimestamp()); repo.setResourceRef(RUtil.jaxbRefToEmbeddedRepoRef(jaxb.getResourceRef(), repositoryContext.prismContext)); repo.setAttemptNumber(jaxb.getAttemptNumber()); repo.setExists(jaxb.isExists()); repo.setDead(jaxb.isDead()); repo.setFailedOperationType(RUtil.getRepoEnumValue(jaxb.getFailedOperationType(), RFailedOperationType.class)); if (jaxb.getResource() != null) { LOGGER.warn("Resource from resource object shadow type won't be saved. It should be " + "translated to resource reference."); } if (jaxb.getAttributes() != null) { copyFromJAXB(jaxb.getAttributes().asPrismContainerValue(), repo, repositoryContext, RObjectExtensionType.ATTRIBUTES); } repo.pendingOperationCount = jaxb.getPendingOperation().size(); } @Override public T toJAXB(PrismContext prismContext, Collection<SelectorOptions<GetOperationOptions>> options) throws DtoTranslationException { ShadowType object = new ShadowType(); RUtil.revive(object, prismContext); RObject.copyToJAXB(this, object, prismContext, options); return (T) object; } }