org.eurekastreams.web.client.ui.common.stream.renderers.StickyActivityRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.eurekastreams.web.client.ui.common.stream.renderers.StickyActivityRenderer.java

Source

/*
 * Copyright (c) 2009-2011 Lockheed Martin Corporation
 *
 * 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 org.eurekastreams.web.client.ui.common.stream.renderers;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.eurekastreams.commons.formatting.DateFormatter;
import org.eurekastreams.server.domain.stream.ActivityDTO;
import org.eurekastreams.server.domain.stream.ActivityVerb;
import org.eurekastreams.server.domain.stream.BaseObjectType;
import org.eurekastreams.server.domain.stream.StreamEntityDTO;
import org.eurekastreams.web.client.model.GroupStickyActivityModel;
import org.eurekastreams.web.client.ui.common.dialog.Dialog;
import org.eurekastreams.web.client.ui.common.pagedlist.ItemRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.StreamMessageItemRenderer.State;
import org.eurekastreams.web.client.ui.common.stream.renderers.object.BookmarkRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.object.FileRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.object.NoteRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.object.ObjectRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.object.VideoRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.verb.PostRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.verb.ShareRenderer;
import org.eurekastreams.web.client.ui.common.stream.renderers.verb.VerbRenderer;
import org.eurekastreams.web.client.ui.common.stream.share.ShareMessageDialogContent;
import org.eurekastreams.web.client.ui.pages.master.StaticResourceBundle;
import org.eurekastreams.web.client.utility.BaseActivityLinkBuilder;
import org.eurekastreams.web.client.utility.InContextActivityLinkBuilder;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.ComplexPanel;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.InlineHyperlink;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.Widget;

/**
 * Renders an activity for the sticky display at the top of the list.
 */
public class StickyActivityRenderer implements ItemRenderer<ActivityDTO> {
    /** Verb dictionary. */
    private final Map<ActivityVerb, VerbRenderer> verbDictionary = new HashMap<ActivityVerb, VerbRenderer>();

    /** Object dictionary. */
    private final Map<BaseObjectType, ObjectRenderer> objectDictionary = new HashMap<BaseObjectType, ObjectRenderer>();

    /** For building links to activities. */
    private final BaseActivityLinkBuilder activityLinkBuilder = new InContextActivityLinkBuilder();

    /**
     * Constructor.
     */
    public StickyActivityRenderer() {
        verbDictionary.put(ActivityVerb.POST, new PostRenderer());
        verbDictionary.put(ActivityVerb.SHARE, new ShareRenderer());

        objectDictionary.put(BaseObjectType.BOOKMARK, new BookmarkRenderer());
        objectDictionary.put(BaseObjectType.NOTE, new NoteRenderer());
        objectDictionary.put(BaseObjectType.VIDEO, new VideoRenderer());
        objectDictionary.put(BaseObjectType.FILE, new FileRenderer());
    }

    /**
     * Render a message item.
     *
     * @param msg
     *            the message item.
     *
     * @return the rendered item as a FlowPanel.
     */
    public Panel render(final ActivityDTO msg) {
        Panel mainPanel = new FlowPanel();
        mainPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().streamMessageItem());
        mainPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().listItem());
        mainPanel.addStyleName(State.READONLY.toString());

        VerbRenderer verbRenderer = verbDictionary.get(msg.getVerb());
        verbRenderer.setup(objectDictionary, msg, State.DEFAULT, false);

        // left column items
        Panel leftColumn = null;

        // avatar
        Widget avatar = verbRenderer.getAvatar();
        if (avatar != null) {
            Panel parent = leftColumn == null ? mainPanel : leftColumn;
            parent.add(avatar);
        }

        FlowPanel msgContent = new FlowPanel();
        msgContent.addStyleName(StaticResourceBundle.INSTANCE.coreCss().description());
        mainPanel.add(msgContent);

        // row for who posted
        Panel sourceMetaData = new FlowPanel();
        sourceMetaData.addStyleName(StaticResourceBundle.INSTANCE.coreCss().messageMetadataSource());
        for (StatefulRenderer itemRenderer : verbRenderer.getSourceMetaDataItemRenderers()) {
            Widget metaDataItem = itemRenderer.render();
            if (metaDataItem != null) {
                sourceMetaData.add(metaDataItem);
            }
        }
        msgContent.add(sourceMetaData);

        // content
        FlowPanel nonMetaData = new FlowPanel();
        nonMetaData.addStyleName(State.READONLY.toString());

        Widget content = verbRenderer.getContent();
        if (content != null) {
            nonMetaData.add(content);
            msgContent.add(nonMetaData);
        }

        // additional metadata
        FlowPanel metaData = new FlowPanel();
        metaData.addStyleName(StaticResourceBundle.INSTANCE.coreCss().messageMetadataAdditional());
        for (StatefulRenderer itemRenderer : verbRenderer.getMetaDataItemRenderers()) {
            Widget metaDataItem = itemRenderer.render();
            if (metaDataItem != null) {
                metaData.add(metaDataItem);
            }
        }
        if (metaData.getWidgetCount() > 0) {
            msgContent.add(metaData);
        }

        msgContent.add(buildActionsLine(msg, verbRenderer));

        return mainPanel;
    }

    /**
     * Builds the action links line.
     *
     * @param msg
     *            The message.
     * @param verbRenderer
     *            Renderer for the message's verb.
     * @return The actions panel.
     */
    private Widget buildActionsLine(final ActivityDTO msg, final VerbRenderer verbRenderer) {
        StreamEntityDTO destinationStream = msg.getDestinationStream();

        // timestamp and actions
        Panel timestampActions = new FlowPanel();
        timestampActions.addStyleName(StaticResourceBundle.INSTANCE.coreCss().messageTimestampActionsArea());

        // Hijack this property and use to show lock icon for private activity.
        if (!msg.isShareable()) {
            Label lockIcon = new Label("");
            lockIcon.addStyleName(StaticResourceBundle.INSTANCE.coreCss().privateIcon());
            timestampActions.add(lockIcon);
        }

        // create timestamp as permalink
        String date = new DateFormatter(new Date()).timeAgo(msg.getPostedTime());
        Widget dateLink;
        String permalinkUrl = activityLinkBuilder.buildActivityPermalink(msg.getId(), destinationStream.getType(),
                destinationStream.getUniqueIdentifier());
        dateLink = new InlineHyperlink(date, permalinkUrl);
        dateLink.addStyleName(StaticResourceBundle.INSTANCE.coreCss().messageTimestampLink());
        timestampActions.add(dateLink);

        if (msg.getAppName() != null) {
            String appSource = msg.getAppSource();
            if (appSource != null) {
                FlowPanel viaPanel = new FlowPanel();
                viaPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().viaMetadata());
                viaPanel.add(new InlineLabel("via "));
                viaPanel.add(new Anchor(msg.getAppName(), appSource));
                timestampActions.add(viaPanel);
            } else {
                InlineLabel viaLine = new InlineLabel("via " + msg.getAppName());
                viaLine.addStyleName(StaticResourceBundle.INSTANCE.coreCss().viaMetadata());
                timestampActions.add(viaLine);
            }
            // TODO: If appSource is not supplied, the link should go to the respective galleries for apps and plugins.
            // However, the app galery requires knowing the start page tab id, and the worthwhile plugin gallery is only
            // available to coordinators.
        }

        ComplexPanel actionsPanel = new FlowPanel();
        actionsPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().messageActionsArea());

        // Show comments
        InlineHyperlink showCommentsLink = new InlineHyperlink("Show Comments", permalinkUrl);
        actionsPanel.add(showCommentsLink);

        // Share
        if (verbRenderer.getAllowShare() && msg.isShareable()) {
            insertActionSeparator(actionsPanel, null);
            Label shareLink = new InlineLabel("Share");
            shareLink.addStyleName(StaticResourceBundle.INSTANCE.coreCss().linkedLabel());
            actionsPanel.add(shareLink);

            shareLink.addClickHandler(new ClickHandler() {
                public void onClick(final ClickEvent event) {
                    Dialog.showCentered(new ShareMessageDialogContent(msg));
                }
            });
        }

        // Unstick
        // Note: using the cheating way: always create the link, let CSS hide it unless the user is actually a
        // coordinator
        insertActionSeparator(actionsPanel, StaticResourceBundle.INSTANCE.coreCss().ownerOnlyInline());
        Label link = new InlineLabel("Unstick");
        link.addStyleName(StaticResourceBundle.INSTANCE.coreCss().linkedLabel());
        link.addStyleName(StaticResourceBundle.INSTANCE.coreCss().ownerOnlyInline());
        actionsPanel.add(link);

        link.addClickHandler(new ClickHandler() {
            public void onClick(final ClickEvent event) {
                GroupStickyActivityModel.getInstance().delete(msg.getDestinationStream().getDestinationEntityId());
            }
        });

        timestampActions.add(actionsPanel);

        return timestampActions;
    }

    /**
     * Adds a separator (dot).
     *
     * @param panel
     *            Panel to put the separator in.
     * @param extraStyle
     *            Extra style to add.
     */
    private void insertActionSeparator(final ComplexPanel panel, final String extraStyle) {
        Label sep = new InlineLabel("\u2219");
        sep.addStyleName(StaticResourceBundle.INSTANCE.coreCss().actionLinkSeparator());
        if (extraStyle != null) {
            sep.addStyleName(extraStyle);
        }
        panel.add(sep);
    }
}