use of com.evolveum.midpoint.repo.sql.util.DtoTranslationException in project midpoint by Evolveum.
the class ObjectUpdater method modifyObjectAttempt.
public <T extends ObjectType> void modifyObjectAttempt(Class<T> type, String oid, Collection<? extends ItemDelta> modifications, RepoModifyOptions modifyOptions, OperationResult result) throws ObjectNotFoundException, SchemaException, ObjectAlreadyExistsException, SerializationRelatedException {
// clone - because some certification and lookup table related methods manipulate this collection and even their constituent deltas
// TODO clone elements only if necessary
modifications = CloneUtil.cloneCollectionMembers(modifications);
//modifications = new ArrayList<>(modifications);
LOGGER.debug("Modifying object '{}' with oid '{}'.", new Object[] { type.getSimpleName(), oid });
LOGGER_PERFORMANCE.debug("> modify object {}, oid={}, modifications={}", type.getSimpleName(), oid, modifications);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Modifications:\n{}", DebugUtil.debugDump(modifications));
}
Session session = null;
OrgClosureManager.Context closureContext = null;
try {
session = baseHelper.beginTransaction();
closureContext = closureManager.onBeginTransactionModify(session, type, oid, modifications);
Collection<? extends ItemDelta> lookupTableModifications = lookupTableHelper.filterLookupTableModifications(type, modifications);
Collection<? extends ItemDelta> campaignCaseModifications = caseHelper.filterCampaignCaseModifications(type, modifications);
if (!modifications.isEmpty() || RepoModifyOptions.isExecuteIfNoChanges(modifyOptions)) {
// JpegPhoto (RFocusPhoto) is a special kind of entity. First of all, it is lazily loaded, because photos are really big.
// Each RFocusPhoto naturally belongs to one RFocus, so it would be appropriate to set orphanRemoval=true for focus-photo
// association. However, this leads to a strange problem when merging in-memory RFocus object with the database state:
// If in-memory RFocus object has no photo associated (because of lazy loading), then the associated RFocusPhoto is deleted.
//
// To prevent this behavior, we've set orphanRemoval to false. Fortunately, the remove operation on RFocus
// seems to be still cascaded to RFocusPhoto. What we have to implement ourselves, however, is removal of RFocusPhoto
// _without_ removing of RFocus. In order to know whether the photo has to be removed, we have to retrieve
// its value, apply the delta (e.g. if the delta is a DELETE VALUE X, we have to know whether X matches current
// value of the photo), and if the resulting value is empty, we have to manually delete the RFocusPhoto instance.
//
// So the first step is to retrieve the current value of photo - we obviously do this only if the modifications
// deal with the jpegPhoto property.
Collection<SelectorOptions<GetOperationOptions>> options;
boolean containsFocusPhotoModification = FocusType.class.isAssignableFrom(type) && containsPhotoModification(modifications);
if (containsFocusPhotoModification) {
options = Collections.singletonList(SelectorOptions.create(FocusType.F_JPEG_PHOTO, GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE)));
} else {
options = null;
}
// get object
PrismObject<T> prismObject = objectRetriever.getObjectInternal(session, type, oid, options, true, result);
// apply diff
LOGGER.trace("OBJECT before:\n{}", prismObject.debugDumpLazily());
PrismObject<T> originalObject = null;
if (closureManager.isEnabled()) {
originalObject = prismObject.clone();
}
ItemDelta.applyTo(modifications, prismObject);
LOGGER.trace("OBJECT after:\n{}", prismObject.debugDumpLazily());
// Continuing the photo treatment: should we remove the (now obsolete) focus photo?
// We have to test prismObject at this place, because updateFullObject (below) removes photo property from the prismObject.
boolean shouldPhotoBeRemoved = containsFocusPhotoModification && ((FocusType) prismObject.asObjectable()).getJpegPhoto() == null;
// merge and update object
LOGGER.trace("Translating JAXB to data type.");
ObjectTypeUtil.normalizeAllRelations(prismObject);
RObject rObject = createDataObjectFromJAXB(prismObject, PrismIdentifierGenerator.Operation.MODIFY);
rObject.setVersion(rObject.getVersion() + 1);
updateFullObject(rObject, prismObject);
LOGGER.trace("Starting merge.");
session.merge(rObject);
if (closureManager.isEnabled()) {
closureManager.updateOrgClosure(originalObject, modifications, session, oid, type, OrgClosureManager.Operation.MODIFY, closureContext);
}
// we have to remove the photo manually.
if (shouldPhotoBeRemoved) {
Query query = session.createQuery("delete RFocusPhoto where ownerOid = :oid");
query.setParameter("oid", prismObject.getOid());
query.executeUpdate();
LOGGER.trace("Focus photo for {} was deleted", prismObject.getOid());
}
}
if (LookupTableType.class.isAssignableFrom(type)) {
lookupTableHelper.updateLookupTableData(session, oid, lookupTableModifications);
}
if (AccessCertificationCampaignType.class.isAssignableFrom(type)) {
caseHelper.updateCampaignCases(session, oid, campaignCaseModifications, modifyOptions);
}
LOGGER.trace("Before commit...");
session.getTransaction().commit();
LOGGER.trace("Committed!");
} catch (ObjectNotFoundException ex) {
baseHelper.rollbackTransaction(session, ex, result, true);
throw ex;
} catch (ConstraintViolationException ex) {
handleConstraintViolationException(session, ex, result);
baseHelper.rollbackTransaction(session, ex, result, true);
LOGGER.debug("Constraint violation occurred (will be rethrown as ObjectAlreadyExistsException).", ex);
//todo improve (we support only 5 DB, so we should probably do some hacking in here)
throw new ObjectAlreadyExistsException(ex);
} catch (SchemaException ex) {
baseHelper.rollbackTransaction(session, ex, result, true);
throw ex;
} catch (DtoTranslationException | RuntimeException ex) {
baseHelper.handleGeneralException(ex, session, result);
} finally {
cleanupClosureAndSessionAndResult(closureContext, session, result);
LOGGER.trace("Session cleaned up.");
}
}
use of com.evolveum.midpoint.repo.sql.util.DtoTranslationException in project midpoint by Evolveum.
the class ROperationalState method copyFromJAXB.
public static void copyFromJAXB(OperationalStateType jaxb, ROperationalState repo) throws DtoTranslationException {
Validate.notNull(repo, "Repo object must not be null.");
Validate.notNull(jaxb, "JAXB object must not be null.");
try {
if (jaxb.getLastAvailabilityStatus() != null) {
repo.setLastAvailabilityStatus(RUtil.getRepoEnumValue(jaxb.getLastAvailabilityStatus(), RAvailabilityStatus.class));
}
} catch (Exception ex) {
throw new DtoTranslationException(ex.getMessage(), ex);
}
}
use of com.evolveum.midpoint.repo.sql.util.DtoTranslationException in project midpoint by Evolveum.
the class RAnyConverter method convertFromRValue.
public void convertFromRValue(RAnyValue value, PrismContainerValue any) throws DtoTranslationException {
Validate.notNull(value, "Value for converting must not be null.");
Validate.notNull(any, "Parent prism container value must not be null.");
try {
Item<?, ?> item = any.findOrCreateItem(RUtil.stringToQName(value.getName()), value.getValueType().getItemClass());
if (item == null) {
throw new DtoTranslationException("Couldn't create item for value '" + value.getName() + "'.");
}
addValueToItem(value, item);
} catch (Exception ex) {
if (ex instanceof DtoTranslationException) {
throw (DtoTranslationException) ex;
}
throw new DtoTranslationException(ex.getMessage(), ex);
}
}
use of com.evolveum.midpoint.repo.sql.util.DtoTranslationException in project midpoint by Evolveum.
the class RObject method copyFromJAXB.
public static void copyFromJAXB(PrismContainerValue containerValue, RObject repo, RepositoryContext repositoryContext, RObjectExtensionType ownerType) throws DtoTranslationException {
RAnyConverter converter = new RAnyConverter(repositoryContext.prismContext);
Set<RAnyValue> values = new HashSet<RAnyValue>();
try {
List<Item<?, ?>> items = containerValue.getItems();
//TODO: is this ehought??should we try items without definitions??
if (items != null) {
for (Item item : items) {
values.addAll(converter.convertToRValue(item, false));
}
}
} catch (Exception ex) {
throw new DtoTranslationException(ex.getMessage(), ex);
}
for (RAnyValue value : values) {
ROExtValue ex = (ROExtValue) value;
ex.setOwner(repo);
ex.setOwnerType(ownerType);
if (value instanceof ROExtDate) {
repo.getDates().add(value);
} else if (value instanceof ROExtLong) {
repo.getLongs().add(value);
} else if (value instanceof ROExtReference) {
repo.getReferences().add(value);
} else if (value instanceof ROExtString) {
repo.getStrings().add(value);
} else if (value instanceof ROExtPolyString) {
repo.getPolys().add(value);
} else if (value instanceof ROExtBoolean) {
repo.getBooleans().add(value);
}
}
repo.setStringsCount((short) repo.getStrings().size());
repo.setDatesCount((short) repo.getDates().size());
repo.setPolysCount((short) repo.getPolys().size());
repo.setReferencesCount((short) repo.getReferences().size());
repo.setLongsCount((short) repo.getLongs().size());
repo.setBooleansCount((short) repo.getBooleans().size());
}
use of com.evolveum.midpoint.repo.sql.util.DtoTranslationException in project midpoint by Evolveum.
the class SqlAuditServiceImpl method listRecordsIterativeAttempt.
private void listRecordsIterativeAttempt(String query, Map<String, Object> params, AuditResultHandler handler) {
Session session = null;
int count = 0;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("List records attempt\n query: {}\n params:\n{}", query, DebugUtil.debugDump(params, 2));
}
try {
session = baseHelper.beginReadOnlyTransaction();
Query q;
if (StringUtils.isBlank(query)) {
query = "from RAuditEventRecord as aer where 1=1 order by aer.timestamp desc";
q = session.createQuery(query);
setParametersToQuery(q, params);
} else {
q = session.createQuery(query);
setParametersToQuery(q, params);
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("List records attempt\n processed query: {}", q);
}
ScrollableResults resultList = q.scroll();
while (resultList.next()) {
Object o = resultList.get(0);
if (!(o instanceof RAuditEventRecord)) {
throw new DtoTranslationException("Unexpected object in result set. Expected audit record, but got " + o.getClass().getSimpleName());
}
RAuditEventRecord raudit = (RAuditEventRecord) o;
AuditEventRecord audit = RAuditEventRecord.fromRepo(raudit, getPrismContext());
// TODO what if original name (in audit log) differs from the current one (in repo) ?
audit.setInitiator(resolve(session, raudit.getInitiatorOid(), raudit.getInitiatorName(), RObjectType.USER));
audit.setTarget(resolve(session, raudit.getTargetOid(), raudit.getTargetName(), raudit.getTargetType()));
audit.setTargetOwner(resolve(session, raudit.getTargetOwnerOid(), raudit.getTargetOwnerName(), RObjectType.USER));
count++;
if (!handler.handle(audit)) {
LOGGER.trace("Skipping handling of objects after {} was handled. ", audit);
break;
}
}
session.getTransaction().commit();
} catch (DtoTranslationException | SchemaException ex) {
baseHelper.handleGeneralCheckedException(ex, session, null);
} catch (RuntimeException ex) {
baseHelper.handleGeneralRuntimeException(ex, session, null);
} finally {
baseHelper.cleanupSessionAndResult(session, null);
}
LOGGER.trace("List records iterative attempt processed {} records", count);
}
Aggregations