com.lyndir.lhunath.snaplog.webapp.view.MediaView.java Source code

Java tutorial

Introduction

Here is the source code for com.lyndir.lhunath.snaplog.webapp.view.MediaView.java

Source

/*
 *   Copyright 2010, Maarten Billemont
 *
 *   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.lyndir.lhunath.snaplog.webapp.view;

import com.google.inject.Inject;
import com.lyndir.lhunath.opal.security.Permission;
import com.lyndir.lhunath.opal.security.error.PermissionDeniedException;
import com.lyndir.lhunath.opal.security.service.SecurityService;
import com.lyndir.lhunath.opal.system.logging.Logger;
import com.lyndir.lhunath.opal.wayward.behavior.CSSClassAttributeAppender;
import com.lyndir.lhunath.opal.wayward.component.GenericPanel;
import com.lyndir.lhunath.snaplog.data.object.media.Media;
import com.lyndir.lhunath.snaplog.data.object.media.Media.Quality;
import com.lyndir.lhunath.snaplog.model.service.impl.SourceDelegate;
import com.lyndir.lhunath.snaplog.webapp.SnaplogSession;
import com.lyndir.lhunath.snaplog.webapp.tab.SharedTabPanel;
import com.lyndir.lhunath.snaplog.webapp.tab.Tab;
import java.net.URL;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.MarkupStream;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.image.ContextImage;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.model.*;

/**
 * <h2>{@link MediaView}<br> <sub>A view that renders media at a certain quality.</sub></h2>
 *
 * <p> <i>Mar 13, 2010</i> </p>
 *
 * @author lhunath
 */
public class MediaView extends GenericPanel<Media> {

    static final Logger logger = Logger.get(MediaView.class);

    @Inject
    SourceDelegate sourceDelegate;

    @Inject
    SecurityService securityService;

    /**
     * @param id        The wicket ID of this component.
     * @param model     The model that will provide the {@link Media} to show in this view.
     * @param quality   The quality at which to show the {@link Media}.
     * @param clickable <code>true</code>: The media will be clickable. When clicked, the {@link #onClick(AjaxRequestTarget)} will be
     *                  fired.<br> <code>false</code>: The media will not be clickable. There is no need to implement {@link
     *                  #onClick(AjaxRequestTarget)}.
     */
    public MediaView(final String id, final IModel<Media> model, final Quality quality, final boolean clickable) {

        super(id, model);

        // The media container.
        WebMarkupContainer media = new WebMarkupContainer("media");
        add(media.add(new AttributeAppender("class", new Model<String>(quality.getName()), " ")));

        // The media image link/container.
        WebMarkupContainer image;
        if (clickable) {
            image = new AjaxFallbackLink<Media>("image", getModel()) {

                @Override
                public void onClick(final AjaxRequestTarget target) {

                    MediaView.this.onClick(target);
                }

                @Override
                public boolean isVisible() {

                    return getModelObject() != null;
                }
            };
            media.add(new CSSClassAttributeAppender("link"));
        } else
            image = new WebMarkupContainer("image") {

                @Override
                public boolean isVisible() {

                    return getModelObject() != null;
                }
            };
        media.add(image);
        media.add(new WebMarkupContainer("tools") {

            {
                add(new ExternalLink("original", new LoadableDetachableModel<String>() {

                    @Override
                    protected String load() {

                        try {
                            URL resourceURL = sourceDelegate.findResourceURL(SnaplogSession.get().newToken(),
                                    getModelObject(), Quality.ORIGINAL);
                            if (resourceURL == null)
                                // TODO: May want to display something useful to the user like a specific "not-found" thumbnail.
                                return null;

                            return resourceURL.toExternalForm();
                        } catch (PermissionDeniedException ignored) {
                            // TODO: May want to display something useful to the user like a specific "denied" thumbnail.
                            return null;
                        }
                    }
                }) {
                    @Override
                    protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {

                        if (!renderAsMini(markupStream, openTag))
                            super.onComponentTagBody(markupStream, openTag);
                    }
                });
                add(new AjaxLink<Media>("share", getModel()) {
                    @Override
                    public void onClick(final AjaxRequestTarget target) {

                        try {
                            Tab.SHARED.activateWithState(new SharedTabPanel.SharedTabState(getModelObject()));
                        } catch (PermissionDeniedException e) {
                            error(e.getLocalizedMessage());
                        }
                    }

                    @Override
                    protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {

                        if (!renderAsMini(markupStream, openTag))
                            super.onComponentTagBody(markupStream, openTag);
                    }

                    @Override
                    public boolean isVisible() {

                        return securityService.hasAccess(Permission.ADMINISTER, SnaplogSession.get().newToken(),
                                getModelObject());
                    }
                });
                add(new WebMarkupContainer("permissions") {
                    @Override
                    protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {

                        if (!renderAsMini(markupStream, openTag))
                            super.onComponentTagBody(markupStream, openTag);
                    }

                    @Override
                    public boolean isVisible() {

                        return securityService.hasAccess(Permission.ADMINISTER, SnaplogSession.get().newToken(),
                                getModelObject());
                    }
                });
                add(new Link<Media>("delete", getModel()) {
                    @Override
                    public void onClick() {

                        try {
                            sourceDelegate.delete(SnaplogSession.get().newToken(), getModelObject());
                        } catch (PermissionDeniedException e) {
                            error(e.getLocalizedMessage());
                        }
                    }

                    @Override
                    protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {

                        if (!renderAsMini(markupStream, openTag))
                            super.onComponentTagBody(markupStream, openTag);
                    }

                    @Override
                    public boolean isVisible() {

                        return securityService.hasAccess(Permission.ADMINISTER, SnaplogSession.get().newToken(),
                                getModelObject());
                    }
                });

                add(CSSClassAttributeAppender.of(new LoadableDetachableModel<String>() {
                    @Override
                    protected String load() {

                        return isMini(quality) ? "mini" : null;
                    }
                }));
            }

            @Override
            public boolean isVisible() {

                return getModelObject() != null;
            }

            private boolean renderAsMini(final MarkupStream markupStream, final ComponentTag openTag) {

                if (isMini(quality)) {
                    // Discard all elements from the markup stream until our close tag.
                    while (markupStream.hasMore())
                        if (markupStream.next().closes(openTag))
                            break;

                    replaceComponentTagBody(markupStream, openTag, "");
                    return true;
                }

                return false;
            }
        });

        image.add(new AttributeModifier("style", true, new LoadableDetachableModel<String>() {

            @Override
            protected String load() {

                try {
                    URL resourceURL = sourceDelegate.findResourceURL(SnaplogSession.get().newToken(),
                            getModelObject(), quality);
                    if (resourceURL == null)
                        // TODO: May want to display something useful to the user like a specific "not-found" thumbnail.
                        return null;

                    return String.format("background-image: url('%s')", resourceURL.toExternalForm());
                } catch (PermissionDeniedException ignored) {
                    // TODO: May want to display something useful to the user like a specific "denied" thumbnail.
                    return null;
                }
            }
        }));
        image.add(new ContextImage("thumb", new LoadableDetachableModel<String>() {

            @Override
            protected String load() {

                logger.dbg("Loading Media: %s, Quality: %s", getModelObject(), quality);

                try {
                    URL resourceURL = sourceDelegate.findResourceURL(SnaplogSession.get().newToken(),
                            getModelObject(), Quality.THUMBNAIL);
                    if (resourceURL == null)
                        // TODO: May want to display something useful to the user like a specific "not-found" thumbnail.
                        return null;

                    return resourceURL.toExternalForm();
                } catch (PermissionDeniedException ignored) {
                    // TODO: May want to display something useful to the user like a specific "denied" thumbnail.
                    return null;
                }
            }
        }));
        image.add(new ContextImage("full", new LoadableDetachableModel<String>() {

            @Override
            protected String load() {

                try {
                    URL resourceURL = sourceDelegate.findResourceURL(SnaplogSession.get().newToken(),
                            getModelObject(), quality);
                    if (resourceURL == null)
                        // TODO: May want to display something useful to the user like a specific "not-found" thumbnail.
                        return null;

                    return resourceURL.toExternalForm();
                } catch (PermissionDeniedException ignored) {
                    // TODO: May want to display something useful to the user like a specific "denied" thumbnail.
                    return null;
                }
            }
        }) {
            @Override
            public boolean isVisible() {

                return quality == Quality.FULLSCREEN;
            }
        });
        image.add(new Label("caption", new LoadableDetachableModel<String>() {

            @Override
            protected String load() {

                return getCaptionString();
            }
        }) {

            @Override
            public boolean isVisible() {

                return getModelObject() != null;
            }
        });
    }

    private static boolean isMini(final Quality quality) {

        return quality == Quality.THUMBNAIL;
    }

    /**
     * @return The string to show in the caption. Use <code>null</code> to hide the caption.
     */
    protected String getCaptionString() {

        return getModelObject().getDateString();
    }

    /**
     * Fired when the user clicks the media.
     *
     * <p> You only need to implement this method when you're actually creating a clickable {@link MediaView}. See the
     * <code>clickable</code> argument of {@link #MediaView(String, IModel, Quality, boolean)}. </p>
     *
     * @param target The AJAX request that fired fired this event.
     */
    protected void onClick(@SuppressWarnings("unused") final AjaxRequestTarget target) {

        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isVisible() {

        return super.isVisible() && getModelObject() != null;
    }
}