/** * Copyright 2010 Google Inc. * * 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.waveprotocol.wave.client.doodad.attachment; import org.waveprotocol.wave.client.doodad.attachment.SimpleAttachmentManager.Attachment; import org.waveprotocol.wave.client.doodad.attachment.SimpleAttachmentManager.UploadStatusCode; import org.waveprotocol.wave.client.doodad.attachment.render.ImageThumbnailRenderer; import org.waveprotocol.wave.client.doodad.attachment.render.ImageThumbnailView; import org.waveprotocol.wave.client.editor.content.ContentElement; import org.waveprotocol.wave.media.model.AttachmentV3.ImageMetadata; import org.waveprotocol.wave.model.util.CollectionUtils; import org.waveprotocol.wave.model.util.IdentityMap; import org.waveprotocol.wave.model.util.Preconditions; /** * Handler for the attachment logic for thumbnail doodads. * * @author danilatos@google.com (Daniel Danilatos) */ public class ImageThumbnailAttachmentHandler implements SimpleAttachmentManager.Listener { // @NotInternationalized private static final String attachmentLoadingFailedTooltip = "Loading attachment failed."; private static final String attachmentMalwareDetected = "The file contains a virus or other malware and has been disabled."; // Memory leak? Should be OK if this handler is per-wavelet private final IdentityMap<Attachment, ContentElement> doodads = CollectionUtils.createIdentityMap(); private ImageThumbnailRenderer renderer; /** NOTE(patcoleman): Not in ctor due to circular dependency. */ void setRenderer(ImageThumbnailRenderer renderer) { Preconditions.checkArgument(renderer != null, "can't bind attachment handler to a null renderer"); Preconditions.checkState(this.renderer == null, "renderer should only be set once"); this.renderer = renderer; } /** * Set up attachment handling for the given element * * @param e the element * @param attachment the attachment */ public void init(ContentElement e, Attachment attachment) { doodads.put(attachment, e); onContentUpdated(attachment); onThumbnailUpdated(attachment); onUploadStatusUpdated(attachment); } /** * Inverse of {@link #init}. */ public void cleanup(ContentElement e, Attachment a) { doodads.remove(a); } private ContentElement getElement(Attachment c) { ContentElement e = doodads.get(c); if (e != null) { if (!e.isContentAttached()) { // Lazy removal. Perhaps do it from the node mutation event handler? doodads.remove(c); } else { return e; } } return null; } @Override public void onContentUpdated(Attachment c) { ContentElement e = getElement(c); // TODO(nigeltao): can e ever be null? if (e == null) { return; } String url = c.getAttachmentUrl(); if (url != null) { renderer.getView(e).setAttachmentUrl(url); } ImageMetadata metadata = c.getContentImageMetadata(); if (metadata != null) { renderer.getView(e).setAttachmentSize(metadata.getWidth(), metadata.getHeight()); } } @Override public void onThumbnailUpdated(Attachment c) { ContentElement e = getElement(c); if (e == null) { return; } if (c.isMalware()) { renderer.getView(e).displayDeadImage(attachmentMalwareDetected); return; } String url = c.getThumbnailUrl(); if (url != null) { renderer.getView(e).setThumbnailUrl(url); } ImageMetadata metadata = c.getThumbnailImageMetadata(); if (metadata != null) { renderer.getView(e).setThumbnailSize(metadata.getWidth(), metadata.getHeight()); } if (metadata == null && c.getUploadStatusCode() == UploadStatusCode.FAILED_AND_NOT_RETRYABLE) { renderer.getView(e).displayDeadImage( attachmentLoadingFailedTooltip); } } @Override public void onUploadStatusUpdated(Attachment c) { ContentElement e = getElement(c); if (e == null) { return; } ImageThumbnailView v = renderer.getView(e); switch (c.getUploadStatusCode()) { case NOT_UPLOADING: case SUCCEEDED: v.hideUploadProgress(); break; case IN_PROGRESS: case FAILED_AND_RETRYABLE: v.setUploadProgress(c.getUploadStatusProgress()); v.showUploadProgress(); break; case FAILED_AND_NOT_RETRYABLE: v.hideUploadProgress(); v.displayDeadImage(attachmentLoadingFailedTooltip); break; default: throw new IllegalStateException(); } } }