package com.celements.model.util; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.apache.commons.lang.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xwiki.component.annotation.Component; import org.xwiki.component.annotation.Requirement; import org.xwiki.model.reference.DocumentReference; import org.xwiki.model.reference.ObjectPropertyReference; import com.celements.model.access.IModelAccessFacade; import com.google.common.base.Objects; import com.xpn.xwiki.doc.XWikiDocument; import com.xpn.xwiki.objects.BaseObject; @Component public class DefaultXObjectUpdateService implements IXObjectUpdateRole { private static Logger LOGGER = LoggerFactory.getLogger(DefaultXObjectUpdateService.class); @Requirement private IModelAccessFacade modelAccess; @Requirement private ModelUtils modelUtils; @Override @Deprecated public boolean updateFromMap(XWikiDocument doc, Map<String, Object> fieldMap) { boolean hasChanged = false; Map<String, BaseObject> objMap = getObjectMap(doc, fieldMap.keySet()); for (String field : fieldMap.keySet()) { ObjectPropertyReference fieldRef = resolveFieldRef(field, doc); BaseObject obj = objMap.get(fieldRef.getParent().getName()); Object newVal = fieldMap.get(field); Object oldVal = modelAccess.getProperty(obj, fieldRef.getName()); if (!ObjectUtils.equals(oldVal, newVal)) { modelAccess.setProperty(obj, fieldRef.getName(), newVal); hasChanged = true; LOGGER.trace("update: '" + field + "' has changed from '" + oldVal + "' to '" + newVal + "'"); } } LOGGER.info("update: for doc " + doc + "' and map '" + fieldMap + "' hasChanged '" + hasChanged + "'"); return hasChanged; } private Map<String, BaseObject> getObjectMap(XWikiDocument doc, Set<String> fields) { Map<String, BaseObject> ret = new HashMap<>(); for (String field : fields) { ObjectPropertyReference fieldRef = resolveFieldRef(field, doc); String className = fieldRef.getParent().getName(); if (!ret.containsKey(className)) { BaseObject obj = modelAccess.getOrCreateXObject(doc, modelUtils.resolveRef(className, DocumentReference.class)); ret.put(className, obj); } } LOGGER.trace("getObjectMap: got for doc '" + doc + "': " + ret.keySet()); return ret; } private ObjectPropertyReference resolveFieldRef(String field, XWikiDocument doc) { return modelUtils.resolveRef(field, ObjectPropertyReference.class, doc.getDocumentReference()); } @Override public boolean update(XWikiDocument doc, Set<ClassFieldValue<?>> fieldValues) { boolean hasChanged = false; for (ClassFieldValue<?> fieldValue : fieldValues) { Object oldVal = modelAccess.getProperty(doc, fieldValue.getField()); if (!Objects.equal(oldVal, fieldValue.getValue())) { modelAccess.setProperty(doc, fieldValue); hasChanged = true; LOGGER.trace("update: '{}' has changed from '{}'", fieldValue.getField(), oldVal); } } LOGGER.info("update: for doc '{}' hasChanged '{}'", doc, hasChanged); return hasChanged; } }