//
// Copyright 2009 Robin Komiwes, Bruno Verachten, Christophe Cordenier
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.wooki.components.activity;
import java.util.List;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.Block;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.annotations.Id;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.Property;
import org.apache.tapestry5.annotations.SetupRender;
import org.apache.tapestry5.internal.services.PageRenderQueue;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.Environment;
import org.apache.tapestry5.services.PartialMarkupRenderer;
import org.apache.tapestry5.services.PartialMarkupRendererFilter;
import com.wooki.MoreEventResult;
import com.wooki.WookiEventConstants;
import com.wooki.domain.model.activity.Activity;
import com.wooki.services.EnumServiceLocator;
import com.wooki.services.activity.ActivityBlockSource;
import com.wooki.services.activity.ActivityDisplayContext;
import com.wooki.services.activity.ActivitySource;
import com.wooki.services.activity.ActivitySourceType;
/**
* Display activities.
*
* @author ccordenier
*/
public class Feed<T extends Activity>
{
@Property
@Parameter(defaultPrefix = BindingConstants.LITERAL, value = "Latest Books")
private String title;
@Property
@Parameter(defaultPrefix = BindingConstants.LITERAL, value = "x460")
private String size;
@Property
@Parameter(defaultPrefix = BindingConstants.BLOCK, allowNull = true)
private Block titleBlock;
@Property
@Parameter(defaultPrefix = BindingConstants.LITERAL, value = "activity-feed")
private String clientId;
@Parameter(defaultPrefix = BindingConstants.LITERAL, value = "BOOK_CREATION")
private ActivitySourceType type;
@Parameter(defaultPrefix = BindingConstants.LITERAL, value = "10")
private int nbElts;
@Parameter
private List<Long> context;
@Inject
@Id("activities")
private Block activitiesBlock;
@Inject
private ActivityBlockSource activitySource;
@Inject
private Environment environment;
@Inject
private PageRenderQueue renderQueue;
@Inject
private EnumServiceLocator locator;
@Property
private List<Activity> activities;
@Property
private Activity current;
@Property
private boolean hasMore;
@Property
private int loopIdx;
private int page;
private ActivitySource source;
/**
* Wrapper around current activity entry.
*
* @author ccordenier
*/
private class FeedActivityDisplayContext implements ActivityDisplayContext
{
public Activity getActivity()
{
return current;
}
public String getStyle()
{
return getCurrentStyle();
}
public boolean isResourceUnavailable()
{
return current.isResourceUnavailable();
}
}
@SetupRender
public void setupActivitiesList()
{
this.source = this.locator.getService(this.type);
int startIdx = nbElts * page;
Long[] parameters = context == null ? null : context.toArray(new Long[context.size()]);
this.activities = this.source.listActivitiesRange(startIdx, this.nbElts, parameters);
this.hasMore = this.activities.size() == nbElts;
}
protected void beginRender()
{
this.environment.push(ActivityDisplayContext.class, new FeedActivityDisplayContext());
}
protected void cleanupRender()
{
this.environment.pop(ActivityDisplayContext.class);
}
@OnEvent(value = WookiEventConstants.UPDATE_MORE_CONTEXT, component = "moreFeeds")
public MoreEventResult moreFeeds(int page)
{
this.page = page;
this.setupActivitiesList();
if (this.activities.size() == 0) { return null; }
MoreEventResult result = new MoreEventResult();
result.setRenderable(this.activitiesBlock);
result.setHasMore(this.activities.size() == this.nbElts);
// Add a filter that will set the environment before rendering elements
renderQueue.addPartialMarkupRendererFilter(new PartialMarkupRendererFilter()
{
public void renderMarkup(MarkupWriter writer, JSONObject reply,
PartialMarkupRenderer renderer)
{
try
{
environment
.push(ActivityDisplayContext.class, new FeedActivityDisplayContext());
renderer.renderMarkup(writer, reply);
}
finally
{
environment.pop(ActivityDisplayContext.class);
}
}
});
return result;
}
/**
* Select the block to display the current activity.
*
* @return
*/
public Block getActivityBlock()
{
return this.activitySource.getActivityBlock(current);
}
public int getMoreContext()
{
return (this.page + this.activities.size() / nbElts);
}
public String getCurrentStyle()
{
return this.loopIdx == 0 && this.page == 0 ? "first" : null;
}
public boolean isDisplayBlock()
{
return this.titleBlock != null;
}
public boolean isResourceAvailable()
{
return !this.current.isResourceUnavailable();
}
}