use of com.xpn.xwiki.objects.classes.BaseClass in project xwiki-platform by xwiki.
the class XWikiDocument method displayForm.
/**
* @since 2.2M1
*/
public String displayForm(DocumentReference classReference, XWikiContext context) {
List<BaseObject> objects = getXObjects(classReference);
if (objects == null) {
return "";
}
BaseObject firstobject = null;
Iterator<BaseObject> foit = objects.iterator();
while ((firstobject == null) && foit.hasNext()) {
firstobject = foit.next();
}
if (firstobject == null) {
return "";
}
BaseClass bclass = firstobject.getXClass(context);
if (bclass.getPropertyList().size() == 0) {
return "";
}
StringBuilder result = new StringBuilder();
result.append("{table}\n");
boolean first = true;
for (String propertyName : bclass.getPropertyList()) {
if (first == true) {
first = false;
} else {
result.append("|");
}
PropertyClass pclass = (PropertyClass) bclass.getField(propertyName);
result.append(pclass.getPrettyName());
}
result.append("\n");
for (int i = 0; i < objects.size(); i++) {
BaseObject object = objects.get(i);
if (object != null) {
first = true;
for (String propertyName : bclass.getPropertyList()) {
if (first == true) {
first = false;
} else {
result.append("|");
}
String data = display(propertyName, object, context);
data = data.trim();
data = data.replaceAll("\n", " ");
if (data.length() == 0) {
result.append(" ");
} else {
result.append(data);
}
}
result.append("\n");
}
}
result.append("{table}\n");
return result.toString();
}
use of com.xpn.xwiki.objects.classes.BaseClass in project xwiki-platform by xwiki.
the class XWikiDocument method getTagsPossibleValues.
public List<String> getTagsPossibleValues(XWikiContext context) {
List<String> list;
try {
BaseClass tagsClass = context.getWiki().getTagClass(context);
String possibleValues = ((StaticListClass) tagsClass.getField(XWikiConstant.TAG_CLASS_PROP_TAGS)).getValues();
return ListClass.getListFromString(possibleValues);
} catch (XWikiException e) {
LOGGER.error("Failed to get tag class", e);
list = Collections.emptyList();
}
return list;
}
use of com.xpn.xwiki.objects.classes.BaseClass in project xwiki-platform by xwiki.
the class XWikiDocument method setTags.
/**
* add tags to the document.
*/
public void setTags(String tagsStr, XWikiContext context) throws XWikiException {
BaseClass tagsClass = context.getWiki().getTagClass(context);
StaticListClass tagProp = (StaticListClass) tagsClass.getField(XWikiConstant.TAG_CLASS_PROP_TAGS);
BaseObject tags = getObject(XWikiConstant.TAG_CLASS, true, context);
tags.safeput(XWikiConstant.TAG_CLASS_PROP_TAGS, tagProp.fromString(tagsStr));
setMetaDataDirty(true);
}
use of com.xpn.xwiki.objects.classes.BaseClass in project xwiki-platform by xwiki.
the class XWikiDocument method parseRequestUpdateOrCreate.
/**
* Generate a map from the request parameters of the form '<spacename>.<classname>_<number>_<propertyname>' Keys of
* this map will be the reference '<spacename>.<classname>' to the Class (for example, 'XWiki.XWikiRights'), the
* content is a list where each element describe property for the object <number>. Element of the list is a map
* where key is <propertyname> and content is the array of corresponding values. Example with a list of HTTP
* parameters:
* <ul>
* <li>XWiki.XWikiRights_0_users=XWiki.Admin</li>
* <li>XWiki.XWikiRights_0_users=XWiki.Me</li>
* <li>XWiki.XWikiRights_0_groups=XWiki.XWikiAllGroup</li>
* <li>XWiki.XWikiRights_1_user=XWiki.Admin</li>
* <li>XWiki.XWikiUsers_1_name=Spirou</li>
* </ul>
* will result in the following map <code><pre>
* {
* "XWiki.XWikiRights": {
* "0": {
* "users": ["XWiki.Admin", "XWiki.Me"],
* "groups": ["XWiki.XWikiAllGroup"]
* },
* "1": {
* "users": ["XWiki.Admin"]
* }
* ],
* "XWiki.XWikiUsers":
* "1": {
* "name": ["Spirou"]
* }
* ]
* }
* </pre></code>
*
* @param request is the input HTTP request that provides the parameters
* @param context
* @return a map containing ordered data
*/
private Map<DocumentReference, SortedMap<Integer, Map<String, String[]>>> parseRequestUpdateOrCreate(XWikiRequest request, XWikiContext context) {
Map<DocumentReference, SortedMap<Integer, Map<String, String[]>>> result = new HashMap<>();
@SuppressWarnings("unchecked") Map<String, String[]> allParameters = request.getParameterMap();
for (Entry<String, String[]> parameter : allParameters.entrySet()) {
Matcher matcher = XPROPERTY_REFERENCE_PATTERN.matcher(parameter.getKey());
if (matcher.matches() == false) {
continue;
}
Integer classNumber;
String className = matcher.group(1);
String classNumberAsString = matcher.group(2);
String classPropertyName = matcher.group(3);
DocumentReference classReference = getCurrentDocumentReferenceResolver().resolve(className);
try {
BaseClass xClass = context.getWiki().getDocument(classReference, context).getXClass();
if (xClass.getPropertyList().contains(classPropertyName) == false) {
continue;
}
classNumber = Integer.parseInt(classNumberAsString);
} catch (XWikiException e) {
// If the class page cannot be found, skip the property update
LOGGER.warn("Failed to load document [{}], ignoring property update [{}]. Reason: [{}]", classReference, parameter.getKey(), ExceptionUtils.getRootCauseMessage(e));
continue;
} catch (NumberFormatException e) {
// If the numner isn't valid, skip the property update
LOGGER.warn("Invalid xobject number [{}], ignoring property update [{}].", classNumberAsString, parameter.getKey());
continue;
}
SortedMap<Integer, Map<String, String[]>> objectMap = result.get(classReference);
if (objectMap == null) {
objectMap = new TreeMap<>();
result.put(classReference, objectMap);
}
// Get the property from the right object #objectNumber of type 'objectName'; create it if they don't exist
Map<String, String[]> object = objectMap.get(classNumber);
if (object == null) {
object = new HashMap<>();
objectMap.put(classNumber, object);
}
object.put(classPropertyName, parameter.getValue());
}
return result;
}
use of com.xpn.xwiki.objects.classes.BaseClass in project xwiki-platform by xwiki.
the class XWikiDocument method merge.
/**
* Apply a 3 ways merge on the current document based on provided previous and new version of the document.
* <p>
* All 3 documents are supposed to have the same document reference and language already since that's what makes
* them uniques.
*
* @param previousDocument the previous version of the document
* @param newDocument the next version of the document
* @param configuration the configuration of the merge indicates how to deal with some conflicts use cases, etc.
* @param context the XWiki context
* @return a repport of what happen during the merge (errors, etc.)
* @since 3.2M1
*/
public MergeResult merge(XWikiDocument previousDocument, XWikiDocument newDocument, MergeConfiguration configuration, XWikiContext context) {
MergeResult mergeResult = new MergeResult();
// Title
setTitle(MergeUtils.mergeOject(previousDocument.getTitle(), newDocument.getTitle(), getTitle(), mergeResult));
// Content
setContent(MergeUtils.mergeLines(previousDocument.getContent(), newDocument.getContent(), getContent(), mergeResult));
// Syntax
setSyntax(MergeUtils.mergeOject(previousDocument.getSyntax(), newDocument.getSyntax(), getSyntax(), mergeResult));
// Default locale
setDefaultLocale(MergeUtils.mergeOject(previousDocument.getDefaultLocale(), newDocument.getDefaultLocale(), getDefaultLocale(), mergeResult));
// Parent
setParentReference(MergeUtils.mergeOject(previousDocument.getRelativeParentReference(), newDocument.getRelativeParentReference(), getRelativeParentReference(), mergeResult));
// DefaultTemplate
setDefaultTemplate(MergeUtils.mergeOject(previousDocument.getDefaultTemplate(), newDocument.getDefaultTemplate(), getDefaultTemplate(), mergeResult));
// Hidden
setHidden(MergeUtils.mergeOject(previousDocument.isHidden(), newDocument.isHidden(), isHidden(), mergeResult));
// CustomClass
setCustomClass(MergeUtils.mergeLines(previousDocument.getCustomClass(), newDocument.getCustomClass(), getCustomClass(), mergeResult));
// ValidationScript
setValidationScript(MergeUtils.mergeLines(previousDocument.getValidationScript(), newDocument.getValidationScript(), getValidationScript(), mergeResult));
// Objects
List<List<ObjectDiff>> objectsDiff = previousDocument.getObjectDiff(previousDocument, newDocument, context);
if (!objectsDiff.isEmpty()) {
// Apply diff on result
for (List<ObjectDiff> objectClassDiff : objectsDiff) {
for (ObjectDiff diff : objectClassDiff) {
BaseObject objectResult = getXObject(diff.getXClassReference(), diff.getNumber());
BaseObject previousObject = previousDocument.getXObject(diff.getXClassReference(), diff.getNumber());
BaseObject newObject = newDocument.getXObject(diff.getXClassReference(), diff.getNumber());
PropertyInterface propertyResult = objectResult != null ? objectResult.getField(diff.getPropName()) : null;
PropertyInterface previousProperty = previousObject != null ? previousObject.getField(diff.getPropName()) : null;
PropertyInterface newProperty = newObject != null ? newObject.getField(diff.getPropName()) : null;
if (diff.getAction() == ObjectDiff.ACTION_OBJECTADDED) {
if (objectResult == null) {
setXObject(newObject.getNumber(), configuration.isProvidedVersionsModifiables() ? newObject : newObject.clone());
mergeResult.setModified(true);
} else {
// collision between DB and new: object to add but already exists in the DB
mergeResult.getLog().error("Collision found on object [{}]", objectResult.getReference());
}
} else if (diff.getAction() == ObjectDiff.ACTION_OBJECTREMOVED) {
if (objectResult != null) {
if (objectResult.equals(previousObject)) {
removeXObject(objectResult);
mergeResult.setModified(true);
} else {
// collision between DB and new: object to remove but not the same as previous
// version
mergeResult.getLog().error("Collision found on object [{}]", objectResult.getReference());
}
} else {
// Already removed from DB, lets assume the user is prescient
mergeResult.getLog().warn("Object [{}] already removed", previousObject.getReference());
}
} else if (previousObject != null && newObject != null) {
if (objectResult != null) {
if (diff.getAction() == ObjectDiff.ACTION_PROPERTYADDED) {
if (propertyResult == null) {
objectResult.safeput(diff.getPropName(), newProperty);
mergeResult.setModified(true);
} else {
// collision between DB and new: property to add but already exists in the DB
mergeResult.getLog().error("Collision found on object property [{}]", propertyResult.getReference());
}
} else if (diff.getAction() == ObjectDiff.ACTION_PROPERTYREMOVED) {
if (propertyResult != null) {
if (propertyResult.equals(previousProperty)) {
objectResult.removeField(diff.getPropName());
mergeResult.setModified(true);
} else {
// collision between DB and new: supposed to be removed but the DB version is
// not the same as the previous version
mergeResult.getLog().error("Collision found on object property [{}]", propertyResult.getReference());
}
} else {
// Already removed from DB, lets assume the user is prescient
mergeResult.getLog().warn("Object property [{}] already removed", previousProperty.getReference());
}
} else if (diff.getAction() == ObjectDiff.ACTION_PROPERTYCHANGED) {
if (propertyResult != null) {
if (propertyResult.equals(previousProperty)) {
objectResult.safeput(diff.getPropName(), newProperty);
mergeResult.setModified(true);
} else {
// Try to apply a 3 ways merge on the property
propertyResult.merge(previousProperty, newProperty, configuration, context, mergeResult);
}
} else {
// collision between DB and new: property to modify but does not exists in DB
// Lets assume it's a mistake to fix
mergeResult.getLog().warn("Object [{}] does not exists", newProperty.getReference());
objectResult.safeput(diff.getPropName(), newProperty);
mergeResult.setModified(true);
}
}
} else {
// Object explitely removed from the DB, lets assume we don't care about the changes
mergeResult.getLog().warn("Object [{}] already removed", previousObject.getReference());
}
}
}
}
}
// Class
BaseClass classResult = getXClass();
BaseClass previousClass = previousDocument.getXClass();
BaseClass newClass = newDocument.getXClass();
classResult.merge(previousClass, newClass, configuration, context, mergeResult);
// Attachments
List<AttachmentDiff> attachmentsDiff = previousDocument.getAttachmentDiff(previousDocument, newDocument, context);
if (!attachmentsDiff.isEmpty()) {
// Apply deleted attachment diff on result (new attachment has already been saved)
for (AttachmentDiff diff : attachmentsDiff) {
XWikiAttachment previousAttachment = diff.getOrigAttachment();
XWikiAttachment nextAttachment = diff.getNewAttachment();
XWikiAttachment attachment = getAttachment(diff.getFileName());
switch(diff.getType()) {
case DELETE:
if (attachment != null) {
try {
if (attachment.equalsData(previousAttachment, context)) {
removeAttachment(attachment);
mergeResult.setModified(true);
} else {
// collision between DB and new: attachment modified by user
mergeResult.getLog().error("Collision found on attachment [{}]", attachment.getReference());
}
} catch (XWikiException e) {
mergeResult.getLog().error("Failed to compare attachments with reference [{}]", attachment.getReference());
}
} else {
// Already removed from DB, lets assume the user is prescient
mergeResult.getLog().warn("Attachment [{}] already removed", previousAttachment.getReference());
}
break;
case INSERT:
if (attachment != null) {
try {
if (!attachment.equalsData(nextAttachment, context)) {
// collision between DB and new: attachment to add but a different one already
// exists in the DB
mergeResult.getLog().error("Collision found on attachment [{}]", attachment.getReference());
} else {
// Already added to the DB, lets assume the user is prescient
mergeResult.getLog().warn("Attachment [{}] already added", previousAttachment.getReference());
}
} catch (XWikiException e) {
mergeResult.getLog().error("Failed to compare attachments with reference [{}]", attachment.getReference());
}
} else {
addAttachment(configuration.isProvidedVersionsModifiables() ? nextAttachment : (XWikiAttachment) nextAttachment.clone());
mergeResult.setModified(true);
}
break;
case CHANGE:
if (attachment != null) {
attachment.merge(previousAttachment, nextAttachment, configuration, context, mergeResult);
} else {
// collision between DB and new: attachment modified but does not exist in the DB
mergeResult.getLog().error("Collision found on attachment [{}]", previousAttachment.getReference());
}
break;
default:
break;
}
}
}
return mergeResult;
}
Aggregations