@Override public SolrInputDocument getSolrDocument(EntityReference entityReference) throws SolrIndexException, IllegalArgumentException { ObjectPropertyReference objectPropertyReference = new ObjectPropertyReference(entityReference); try { SolrInputDocument solrDocument = new SolrInputDocument(); BaseObjectReference objectReference = new BaseObjectReference(objectPropertyReference.getParent()); DocumentReference classReference = objectReference.getXClassReference(); DocumentReference documentReference = new DocumentReference(objectReference.getParent()); XWikiDocument document = getDocument(documentReference); BaseProperty<ObjectPropertyReference> objectProperty = document.getXObjectProperty(objectPropertyReference); solrDocument.addField(Fields.ID, getId(objectPropertyReference)); addDocumentFields(documentReference, solrDocument); solrDocument.addField(Fields.TYPE, objectPropertyReference.getType().name()); solrDocument.addField(Fields.CLASS, localSerializer.serialize(classReference)); solrDocument.addField(Fields.PROPERTY_NAME, objectProperty.getName()); addLanguageAndContentFields(documentReference, solrDocument, objectProperty); return solrDocument; } catch (Exception e) { throw new SolrIndexException( String.format("Failed to get Solr document for '%s'", objectPropertyReference), e); } }
/** * Set the language to all the translations that the owning document has. This ensures that this * entity is found for all the translations of a document, not just the original document. * * <p>Also, index the content with each language so that the right analyzer is used. * * @param documentReference the original document's reference. * @param solrDocument the Solr document where to add the fields. * @param objectProperty the object property. * @throws Exception if problems occur. */ protected void addLanguageAndContentFields( DocumentReference documentReference, SolrInputDocument solrDocument, BaseProperty<ObjectPropertyReference> objectProperty) throws Exception { XWikiDocument originalDocument = getDocument(documentReference); // Get all the languages in which the document is available. List<String> documentLanguages = originalDocument.getTranslationList(getXWikiContext()); // Make sure that the original document's language is there as well. String originalDocumentLanguage = getLanguage(documentReference); if (!documentLanguages.contains(originalDocumentLanguage)) { documentLanguages.add(originalDocumentLanguage); } // Do the work for each language. for (String documentLanguage : documentLanguages) { if (!documentLanguage.equals(originalDocumentLanguage)) { // The original document's language is already set by the call to the addDocumentFields // method. solrDocument.addField(Fields.LANGUAGE, documentLanguage); } solrDocument.addField( String.format(Fields.MULTILIGNUAL_FORMAT, Fields.PROPERTY_VALUE, documentLanguage), objectProperty.getValue()); } // We can`t rely on the schema's copyField here because we would trigger it for each language. // Doing the copy to // the text_general field manually. solrDocument.addField( String.format(Fields.MULTILIGNUAL_FORMAT, Fields.PROPERTY_VALUE, Fields.MULTILINGUAL), objectProperty.getValue()); }
/** * Retrieves deprecated properties of the given object compared to the class. A deprecated * property is a property which exists in the Object but doesn't exist anymore in the Class, or * which has the wrong data type. This is used for synchronization of existing or imported Objects * with respect to the modifications of their associated Class. * * @param object the instance of this class where to look for undefined properties * @return an unmodifiable list containing the properties of the object which don't exist in the * class * @since 2.4M2 */ public List<BaseProperty> getDeprecatedObjectProperties(BaseObject object) { @SuppressWarnings("unchecked") Collection<BaseProperty> objectProperties = object.getFieldList(); if (objectProperties == null) { return Collections.emptyList(); } List<BaseProperty> deprecatedObjectProperties = new ArrayList<BaseProperty>(); for (BaseProperty property : objectProperties) { if (safeget(property.getName()) == null) { deprecatedObjectProperties.add(property); } else { String propertyClass = ((PropertyClass) safeget(property.getName())).newProperty().getClassType(); String objectPropertyClass = property.getClassType(); if (!propertyClass.equals(objectPropertyClass)) { deprecatedObjectProperties.add(property); } } } return Collections.unmodifiableList(deprecatedObjectProperties); }
@Override public void displayEdit( StringBuffer buffer, String name, String prefix, BaseCollection object, XWikiContext context) { input input = new input(); input.setAttributeFilter(new XMLAttributeValueFilter()); BaseProperty prop = (BaseProperty) object.safeget(name); if (prop != null) { input.setValue(prop.toText()); } input.setType("text"); input.setName(prefix + name); input.setID(prefix + name); input.setSize(getSize()); input.setDisabled(isDisabled()); if (isPicker()) { input.setClass("suggested"); String path = ""; XWiki xwiki = context.getWiki(); path = xwiki.getURL("Main.WebHome", "view", context); String classname = this.getObject().getName(); String fieldname = this.getName(); String secondCol = "-", firstCol = "-"; String script = "\"" + path + "?xpage=suggest&classname=" + classname + "&fieldname=" + fieldname + "&firCol=" + firstCol + "&secCol=" + secondCol + "&\""; String varname = "\"input\""; input.setOnFocus("new ajaxSuggest(this, {script:" + script + ", varname:" + varname + "} )"); } buffer.append(input.toString()); }
public BaseCollection fromValueMap(Map<String, ?> map, BaseCollection object) { for (PropertyClass property : (Collection<PropertyClass>) getFieldList()) { String name = property.getName(); Object formvalue = map.get(name); if (formvalue != null) { BaseProperty objprop; objprop = property.fromValue(formvalue); if (objprop != null) { objprop.setObject(object); object.safeput(name, objprop); } } } return object; }
public BaseCollection fromMap(Map<String, ?> map, BaseCollection object) { for (PropertyClass property : (Collection<PropertyClass>) getFieldList()) { String name = property.getName(); Object formvalues = map.get(name); if (formvalues != null) { BaseProperty objprop; if (formvalues instanceof String[]) { objprop = property.fromStringArray(((String[]) formvalues)); } else { objprop = property.fromString(formvalues.toString()); } if (objprop != null) { objprop.setObject(object); object.safeput(name, objprop); } } } return object; }
@Override public List<String> toList(BaseProperty<?> property) { List<String> selectlist; if (property == null) { selectlist = new ArrayList<String>(); } else { selectlist = getListFromString((String) property.getValue()); } return selectlist; }
@Test public void getDocumentWithObjects() throws Exception { DocumentReference commentsClassReference = new DocumentReference("wiki", "space", "commentsClass"); String commentContent = "This is a comment"; String commentAuthor = "wiki:space.commentAuthor"; Date commentDate = new Date(); // Adding a fake password field to the comments class just to test the branch in the code. String commentPassword = "******"; List<String> commentList = Arrays.asList("a", "list"); List<BaseProperty<EntityReference>> commentFields = new ArrayList<BaseProperty<EntityReference>>(); // Mock BaseProperty<EntityReference> mockCommentField = mock(BaseProperty.class); when(mockCommentField.getName()).thenReturn("comment"); when(mockCommentField.getValue()).thenReturn(commentContent); commentFields.add(mockCommentField); BaseProperty<EntityReference> mockAuthorField = mock(BaseProperty.class); when(mockAuthorField.getName()).thenReturn("author"); when(mockAuthorField.getValue()).thenReturn(commentAuthor); commentFields.add(mockAuthorField); BaseProperty<EntityReference> mockDateField = mock(BaseProperty.class); when(mockDateField.getName()).thenReturn("date"); when(mockDateField.getValue()).thenReturn(commentDate); commentFields.add(mockDateField); BaseProperty<EntityReference> mockPasswordField = mock(BaseProperty.class); when(mockPasswordField.getName()).thenReturn("password"); when(mockPasswordField.getValue()).thenReturn(commentPassword); commentFields.add(mockPasswordField); BaseProperty<EntityReference> mockListField = mock(BaseProperty.class); when(mockListField.getName()).thenReturn("list"); when(mockListField.getValue()).thenReturn(commentList); commentFields.add(mockListField); BaseClass mockXClass = mock(BaseClass.class); BaseObject mockComment = mock(BaseObject.class); // When handled as a comment Vector<BaseObject> comments = new Vector<BaseObject>(); comments.add(mockComment); when(mockDocument.getComments()).thenReturn(comments); when(mockComment.getStringValue("comment")).thenReturn(commentContent); when(mockComment.getStringValue("author")).thenReturn(commentAuthor); when(mockComment.getDateValue("date")).thenReturn(commentDate); // When handled as a general object HashMap<DocumentReference, List<BaseObject>> xObjects = new HashMap<DocumentReference, List<BaseObject>>(); xObjects.put(commentsClassReference, Arrays.asList(mockComment)); when(mockDocument.getXObjects()).thenReturn(xObjects); when(mockComment.getXClass(mockContext)).thenReturn(mockXClass); when(mockComment.getFieldList()).thenReturn(commentFields); PropertyClass passwordClass = mock(PasswordClass.class); when(mockXClass.get("password")).thenReturn(passwordClass); when(passwordClass.getClassType()).thenReturn("Password"); // Call DocumentSolrMetadataExtractor extractor = (DocumentSolrMetadataExtractor) mocker.getComponentUnderTest(); SolrInputDocument solrDocument = extractor.getSolrDocument(documentReference); // Assert and verify Assert.assertEquals( String.format("%s by %s on %s", commentContent, commentAuthor, commentDate), solrDocument.getFieldValue( String.format(Fields.MULTILIGNUAL_FORMAT, Fields.COMMENT, language))); Collection<Object> objectProperties = solrDocument.getFieldValues( String.format(Fields.MULTILIGNUAL_FORMAT, Fields.OBJECT_CONTENT, language)); MatcherAssert.assertThat( objectProperties, Matchers.containsInAnyOrder( (Object) ("comment:" + commentContent), (Object) ("author:" + commentAuthor), (Object) ("date:" + commentDate.toString()), (Object) ("list:" + commentList.get(0)), (Object) ("list:" + commentList.get(1)))); Assert.assertEquals(5, objectProperties.size()); }
/** * Remove deprecated fields (properties deleted from the XClass) from an object. * * @param object the object to synchronize * @param context the current request context */ private void synchronizeObject(BaseObject object, XWikiContext context) { for (BaseProperty property : object.getXClass(context).getDeprecatedObjectProperties(object)) { object.removeField(property.getName()); } }
@Override public BaseProperty newProperty() { BaseProperty property = new StringProperty(); property.setName(getName()); return property; }
@Override public BaseProperty fromString(String value) { BaseProperty property = newProperty(); property.setValue(value); return property; }
@Override public void fromList(BaseProperty<?> property, List<String> list) { property.setValue(list != null ? StringUtils.join(list, ',') : null); }
public static Object createObject( ObjectFactory objectFactory, URI baseUri, XWikiContext xwikiContext, Document doc, BaseObject xwikiObject, boolean useVersion, XWiki xwikiApi, Boolean withPrettyNames) throws XWikiException { Object object = objectFactory.createObject(); fillObjectSummary(object, objectFactory, baseUri, doc, xwikiObject, xwikiApi, withPrettyNames); BaseClass xwikiClass = xwikiObject.getXClass(xwikiContext); for (java.lang.Object propertyClassObject : xwikiClass.getProperties()) { com.xpn.xwiki.objects.classes.PropertyClass propertyClass = (com.xpn.xwiki.objects.classes.PropertyClass) propertyClassObject; Property property = objectFactory.createProperty(); for (java.lang.Object o : propertyClass.getProperties()) { BaseProperty baseProperty = (BaseProperty) o; Attribute attribute = objectFactory.createAttribute(); attribute.setName(baseProperty.getName()); /* Check for null values in order to prevent NPEs */ if (baseProperty.getValue() != null) { attribute.setValue(baseProperty.getValue().toString()); } else { attribute.setValue(""); } property.getAttributes().add(attribute); } if (propertyClass instanceof ListClass) { ListClass listClass = (ListClass) propertyClass; List allowedValueList = listClass.getList(xwikiContext); if (!allowedValueList.isEmpty()) { Formatter f = new Formatter(); for (int i = 0; i < allowedValueList.size(); i++) { if (i != allowedValueList.size() - 1) { f.format("%s,", allowedValueList.get(i).toString()); } else { f.format("%s", allowedValueList.get(i).toString()); } } Attribute attribute = objectFactory.createAttribute(); attribute.setName(Constants.ALLOWED_VALUES_ATTRIBUTE_NAME); attribute.setValue(f.toString()); property.getAttributes().add(attribute); } } property.setName(propertyClass.getName()); property.setType(propertyClass.getClassType()); if (xwikiObject.get(propertyClass.getName()) != null) { property.setValue(xwikiObject.get(propertyClass.getName()).toFormString()); } else { property.setValue(""); } String propertyUri; if (useVersion) { propertyUri = uri( baseUri, ObjectPropertyAtPageVersionResource.class, doc.getWiki(), doc.getSpace(), doc.getName(), doc.getVersion(), xwikiObject.getClassName(), xwikiObject.getNumber(), propertyClass.getName()); } else { propertyUri = uri( baseUri, ObjectPropertyResource.class, doc.getWiki(), doc.getSpace(), doc.getName(), xwikiObject.getClassName(), xwikiObject.getNumber(), propertyClass.getName()); } Link propertyLink = objectFactory.createLink(); propertyLink.setHref(propertyUri); propertyLink.setRel(Relations.SELF); property.getLinks().add(propertyLink); object.getProperties().add(property); } Link objectLink = getObjectLink(objectFactory, baseUri, doc, xwikiObject, useVersion, Relations.SELF); object.getLinks().add(objectLink); return object; }