Hi Marius
Collections.EMPTY_MAP is used to fill a
"missing" parameter when a
method is overloaded. Use the signature that specifies the parameter:
public SyndEntrySourceApi getSyndEntryArticleSource()
public SyndEntrySourceApi getSyndEntryArticleSource(Map params)
I noticed that but the problem is that later
these maps are used to
Used where? In your code or in the feed plug-in code? I doubt it's in
the feed plug-in code because the semantic I choose was: if you don't
specify any parameters then you don't have any parameters and thus
there's no need to change the map. If you want to specify parameters
then you have to provide at least an empty (mutable) map.
Can you give me a code snipped that shows the failure?
Calling getBlogFeed(String,int,int):
public SyndFeed getBlogFeed(String query, int count, int start)
{
return getBlogFeed(query, count, start, Collections.EMPTY_MAP);
}
Call THIS:
public SyndFeed getBlogFeed(String query, int count, int start, Map metadata)
{
if (query == null) {
XWikiRequest request = getXWikiContext().getRequest();
String category = request.getParameter("category");
if (category == null || category.equals("")) {
query =
", BaseObject as obj where obj.name=doc.fullName and
obj.className='XWiki.ArticleClass' and
obj.name<>'XWiki.ArticleClassTemplate' order by doc.creationDate
desc";
} else {
query =
", BaseObject as obj, DBStringListProperty as prop join prop.list
list where obj.name=doc.fullName and obj.className='XWiki.ArticleClass' and
obj.name<>'XWiki.ArticleClassTemplate' and obj.id=prop.id.id and
prop.id.name='category' and list = '"
+ category + "' order by doc.creationDate desc";
}
}
SyndFeed blogFeed = getArticleFeed(query, count, start,
fillBlogFeedMetadata(metadata));
if (blogFeed != null) {
blogFeed.setImage(getDefaultFeedImage());
}
return blogFeed;
}
which calls THIS:
private Map fillWebFeedMetadata(Map metadata)
{
fillDefaultFeedMetadata(metadata);
// these strings should be taken from a resource bundle
String title = "Feed for document changes";
String description = title;
if (!keyHasValue(metadata, "title", "")) {
metadata.put("title", title);
}
if (!keyHasValue(metadata, "description", "")) {
metadata.put("description", description);
}
return metadata;
}
which calls THIS where it fails because the MAP is immutable:
private Map fillDefaultFeedMetadata(Map metadata)
{
XWiki xwiki = getXWikiContext().getWiki();
XWikiDocument doc = getXWikiContext().getDoc();
if (metadata.get("author") == null) {
metadata.put("author", xwiki.getUserName(doc.getAuthor(), null,
false, getXWikiContext()));
}
if (!keyHasValue(metadata, "copyright", "")) {
metadata.put("copyright",
xwiki.getWebCopyright(getXWikiContext()));
}
if (!keyHasValue(metadata, "encoding", "")) {
metadata.put("encoding", xwiki.getEncoding());
}
if (!keyHasValue(metadata, "url", "")) {
metadata.put("url", "http://" +
getXWikiContext().getRequest().getServerName());
}
if (!keyHasValue(metadata, "language", "")) {
metadata.put("language", doc.getDefaultLanguage());
}
return metadata;
}
> The FeedPlugin has two problems. A default query
is not working
> because it looks for XWiki.ArticleClass which I changed but also it
> uses the XWiki.ArticleClass to define the properties to read out the
> values and that fails with a NPE:
Here is where XWiki.ArticleClass is used:
public SyndFeed getBlogFeed(String query, int count, int start, Map metadata)
{
if (query == null) {
XWikiRequest request = getXWikiContext().getRequest();
String category = request.getParameter("category");
if (category == null || category.equals("")) {
query =
", BaseObject as obj where obj.name=doc.fullName and
obj.className='XWiki.ArticleClass' and
obj.name<>'XWiki.ArticleClassTemplate' order by doc.creationDate
desc";
} else {
query =
", BaseObject as obj, DBStringListProperty as prop join prop.list
list where obj.name=doc.fullName and obj.className='XWiki.ArticleClass' and
obj.name<>'XWiki.ArticleClassTemplate' and obj.id=prop.id.id and
prop.id.name='category' and list = '"
+ category + "' order by doc.creationDate desc";
}
}
SyndFeed blogFeed = getArticleFeed(query, count, start,
fillBlogFeedMetadata(metadata));
if (blogFeed != null) {
blogFeed.setImage(getDefaultFeedImage());
}
return blogFeed;
}
I had to
change the Source
Parameters in order to make it work. I will have a closer look at the
Feed Plugin and provide a patch when I could make it work.
Again, can you provide a code snipped that shows the issue?
SyndEntryDocumentSource is a generic feed entry source that knows
nothing about XWiki.ArticleClass. It can generate a feed entry by
collecting values from different properties of different objects
attached to the source document. You can even specify velocity
expressions to fill feed entry fields.
Feed plug-in provides some helper methods for generating a feed from
XWiki.ArticleClass objects. Forget about it. For the new blog you have
to use the generic API and specify the mapping between feed entry fields
and Blog.BlogPostClass properties. Take a closer look at my example
http://tinyurl.com/cps7oa . As you can see I map:
* ContentLength field -> a constant, 10
* title field -> document title
* description field -> the content property of the first
XWiki.ArticleClass object attached to the source document
* publishedDate -> the date property of the XWiki.ArticleClass object
with index 0 among all the XWiki.ArticleClass objects attached to the
source document
* updatedDate -> a velocity expression, $doc.date.time
* categories -> a list: $doc.space, $doc.name, $doc.isNew()
So what stops you from mapping feed entry fields to Blog.BlogPostClass
properties ?
If we have methods that provide default values shouldn't it then work. The
SyndEntryDocumentSource uses the XWiki.ArticleClass as the default mapping for the
properties and it fails silently if the properties cannot be found.
Shouldn't we then provide a default mapping for getBlogFeed() methods that don't
have one?
I will use the code snipped you mentioned above and see if I can make it work with 2.0m2
when it comes out.
Thanks - Andy