Search in sources :

Example 21 with BaseClass

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("&nbsp;");
                } else {
                    result.append(data);
                }
            }
            result.append("\n");
        }
    }
    result.append("{table}\n");
    return result.toString();
}
Also used : BaseClass(com.xpn.xwiki.objects.classes.BaseClass) ToString(org.suigeneris.jrcs.util.ToString) PropertyClass(com.xpn.xwiki.objects.classes.PropertyClass) BaseObject(com.xpn.xwiki.objects.BaseObject)

Example 22 with BaseClass

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;
}
Also used : StaticListClass(com.xpn.xwiki.objects.classes.StaticListClass) BaseClass(com.xpn.xwiki.objects.classes.BaseClass) ToString(org.suigeneris.jrcs.util.ToString) XWikiException(com.xpn.xwiki.XWikiException)

Example 23 with BaseClass

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);
}
Also used : StaticListClass(com.xpn.xwiki.objects.classes.StaticListClass) BaseClass(com.xpn.xwiki.objects.classes.BaseClass) BaseObject(com.xpn.xwiki.objects.BaseObject)

Example 24 with BaseClass

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;
}
Also used : HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) ClassBlockMatcher(org.xwiki.rendering.block.match.ClassBlockMatcher) MacroBlockMatcher(org.xwiki.rendering.block.match.MacroBlockMatcher) ToString(org.suigeneris.jrcs.util.ToString) SortedMap(java.util.SortedMap) BaseClass(com.xpn.xwiki.objects.classes.BaseClass) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) HashMap(java.util.HashMap) DocumentReference(org.xwiki.model.reference.DocumentReference) LocalDocumentReference(org.xwiki.model.reference.LocalDocumentReference) XWikiException(com.xpn.xwiki.XWikiException)

Example 25 with BaseClass

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;
}
Also used : ObjectDiff(com.xpn.xwiki.objects.ObjectDiff) PropertyInterface(com.xpn.xwiki.objects.PropertyInterface) MergeResult(com.xpn.xwiki.doc.merge.MergeResult) BaseClass(com.xpn.xwiki.objects.classes.BaseClass) XWikiAttachmentList(com.xpn.xwiki.internal.doc.XWikiAttachmentList) ArrayList(java.util.ArrayList) List(java.util.List) XWikiException(com.xpn.xwiki.XWikiException) BaseObject(com.xpn.xwiki.objects.BaseObject)

Aggregations

BaseClass (com.xpn.xwiki.objects.classes.BaseClass)100 DocumentReference (org.xwiki.model.reference.DocumentReference)42 XWikiDocument (com.xpn.xwiki.doc.XWikiDocument)41 BaseObject (com.xpn.xwiki.objects.BaseObject)40 XWikiException (com.xpn.xwiki.XWikiException)26 XWikiContext (com.xpn.xwiki.XWikiContext)24 ArrayList (java.util.ArrayList)18 PropertyClass (com.xpn.xwiki.objects.classes.PropertyClass)16 XWiki (com.xpn.xwiki.XWiki)15 Test (org.junit.Test)15 LocalDocumentReference (org.xwiki.model.reference.LocalDocumentReference)15 EntityReference (org.xwiki.model.reference.EntityReference)10 XWikiAttachment (com.xpn.xwiki.doc.XWikiAttachment)9 BaseProperty (com.xpn.xwiki.objects.BaseProperty)9 List (java.util.List)9 ToString (org.suigeneris.jrcs.util.ToString)9 ComponentLookupException (org.xwiki.component.manager.ComponentLookupException)7 Before (org.junit.Before)6 TextAreaClass (com.xpn.xwiki.objects.classes.TextAreaClass)5 MigrationRequiredException (com.xpn.xwiki.store.migration.MigrationRequiredException)5