/**
* 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();
}
}
}